diff options
-rw-r--r-- | arch/s390/kernel/early.c | 109 | ||||
-rw-r--r-- | arch/s390/kernel/head31.S | 61 | ||||
-rw-r--r-- | arch/s390/kernel/head64.S | 62 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 2 | ||||
-rw-r--r-- | include/asm-s390/setup.h | 33 | ||||
-rw-r--r-- | include/asm-s390/smp.h | 6 | ||||
-rw-r--r-- | include/asm-s390/system.h | 8 |
7 files changed, 140 insertions, 141 deletions
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 68ec4083bf73..bd188f6bd0e2 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -139,15 +139,15 @@ static noinline __init void detect_machine_type(void) | |||
139 | 139 | ||
140 | /* Running under z/VM ? */ | 140 | /* Running under z/VM ? */ |
141 | if (cpuinfo->cpu_id.version == 0xff) | 141 | if (cpuinfo->cpu_id.version == 0xff) |
142 | machine_flags |= 1; | 142 | machine_flags |= MACHINE_FLAG_VM; |
143 | 143 | ||
144 | /* Running on a P/390 ? */ | 144 | /* Running on a P/390 ? */ |
145 | if (cpuinfo->cpu_id.machine == 0x7490) | 145 | if (cpuinfo->cpu_id.machine == 0x7490) |
146 | machine_flags |= 4; | 146 | machine_flags |= MACHINE_FLAG_P390; |
147 | 147 | ||
148 | /* Running under KVM ? */ | 148 | /* Running under KVM ? */ |
149 | if (cpuinfo->cpu_id.version == 0xfe) | 149 | if (cpuinfo->cpu_id.version == 0xfe) |
150 | machine_flags |= 64; | 150 | machine_flags |= MACHINE_FLAG_KVM; |
151 | } | 151 | } |
152 | 152 | ||
153 | #ifdef CONFIG_64BIT | 153 | #ifdef CONFIG_64BIT |
@@ -268,6 +268,103 @@ static noinline __init void setup_lowcore_early(void) | |||
268 | s390_base_pgm_handler_fn = early_pgm_check_handler; | 268 | s390_base_pgm_handler_fn = early_pgm_check_handler; |
269 | } | 269 | } |
270 | 270 | ||
271 | static __init void detect_mvpg(void) | ||
272 | { | ||
273 | #ifndef CONFIG_64BIT | ||
274 | int rc; | ||
275 | |||
276 | asm volatile( | ||
277 | " la 0,0\n" | ||
278 | " mvpg %2,%2\n" | ||
279 | "0: la %0,0\n" | ||
280 | "1:\n" | ||
281 | EX_TABLE(0b,1b) | ||
282 | : "=d" (rc) : "0" (-EOPNOTSUPP), "a" (0) : "memory", "cc", "0"); | ||
283 | if (!rc) | ||
284 | machine_flags |= MACHINE_FLAG_MVPG; | ||
285 | #endif | ||
286 | } | ||
287 | |||
288 | static __init void detect_ieee(void) | ||
289 | { | ||
290 | #ifndef CONFIG_64BIT | ||
291 | int rc, tmp; | ||
292 | |||
293 | asm volatile( | ||
294 | " efpc %1,0\n" | ||
295 | "0: la %0,0\n" | ||
296 | "1:\n" | ||
297 | EX_TABLE(0b,1b) | ||
298 | : "=d" (rc), "=d" (tmp): "0" (-EOPNOTSUPP) : "cc"); | ||
299 | if (!rc) | ||
300 | machine_flags |= MACHINE_FLAG_IEEE; | ||
301 | #endif | ||
302 | } | ||
303 | |||
304 | static __init void detect_csp(void) | ||
305 | { | ||
306 | #ifndef CONFIG_64BIT | ||
307 | int rc; | ||
308 | |||
309 | asm volatile( | ||
310 | " la 0,0\n" | ||
311 | " la 1,0\n" | ||
312 | " la 2,4\n" | ||
313 | " csp 0,2\n" | ||
314 | "0: la %0,0\n" | ||
315 | "1:\n" | ||
316 | EX_TABLE(0b,1b) | ||
317 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc", "0", "1", "2"); | ||
318 | if (!rc) | ||
319 | machine_flags |= MACHINE_FLAG_CSP; | ||
320 | #endif | ||
321 | } | ||
322 | |||
323 | static __init void detect_diag9c(void) | ||
324 | { | ||
325 | unsigned int cpu_address; | ||
326 | int rc; | ||
327 | |||
328 | cpu_address = stap(); | ||
329 | asm volatile( | ||
330 | " diag %2,0,0x9c\n" | ||
331 | "0: la %0,0\n" | ||
332 | "1:\n" | ||
333 | EX_TABLE(0b,1b) | ||
334 | : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc"); | ||
335 | if (!rc) | ||
336 | machine_flags |= MACHINE_FLAG_DIAG9C; | ||
337 | } | ||
338 | |||
339 | static __init void detect_diag44(void) | ||
340 | { | ||
341 | #ifdef CONFIG_64BIT | ||
342 | int rc; | ||
343 | |||
344 | asm volatile( | ||
345 | " diag 0,0,0x44\n" | ||
346 | "0: la %0,0\n" | ||
347 | "1:\n" | ||
348 | EX_TABLE(0b,1b) | ||
349 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc"); | ||
350 | if (!rc) | ||
351 | machine_flags |= MACHINE_FLAG_DIAG44; | ||
352 | #endif | ||
353 | } | ||
354 | |||
355 | static __init void detect_machine_facilities(void) | ||
356 | { | ||
357 | #ifdef CONFIG_64BIT | ||
358 | unsigned int facilities; | ||
359 | |||
360 | facilities = stfl(); | ||
361 | if (facilities & (1 << 28)) | ||
362 | machine_flags |= MACHINE_FLAG_IDTE; | ||
363 | if (facilities & (1 << 4)) | ||
364 | machine_flags |= MACHINE_FLAG_MVCOS; | ||
365 | #endif | ||
366 | } | ||
367 | |||
271 | /* | 368 | /* |
272 | * Save ipl parameters, clear bss memory, initialize storage keys | 369 | * Save ipl parameters, clear bss memory, initialize storage keys |
273 | * and create a kernel NSS at startup if the SAVESYS= parm is defined | 370 | * and create a kernel NSS at startup if the SAVESYS= parm is defined |
@@ -285,6 +382,12 @@ void __init startup_init(void) | |||
285 | create_kernel_nss(); | 382 | create_kernel_nss(); |
286 | sort_main_extable(); | 383 | sort_main_extable(); |
287 | setup_lowcore_early(); | 384 | setup_lowcore_early(); |
385 | detect_mvpg(); | ||
386 | detect_ieee(); | ||
387 | detect_csp(); | ||
388 | detect_diag9c(); | ||
389 | detect_diag44(); | ||
390 | detect_machine_facilities(); | ||
288 | sclp_read_info_early(); | 391 | sclp_read_info_early(); |
289 | sclp_facilities_detect(); | 392 | sclp_facilities_detect(); |
290 | memsize = sclp_memory_detect(); | 393 | memsize = sclp_memory_detect(); |
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index dc364c1419af..a816e2de32b9 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S | |||
@@ -57,61 +57,6 @@ startup_continue: | |||
57 | # | 57 | # |
58 | l %r14,.Lstartup_init-.LPG1(%r13) | 58 | l %r14,.Lstartup_init-.LPG1(%r13) |
59 | basr %r14,%r14 | 59 | basr %r14,%r14 |
60 | |||
61 | l %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags | ||
62 | # | ||
63 | # find out if we have an IEEE fpu | ||
64 | # | ||
65 | mvc __LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13) | ||
66 | efpc %r0,0 # test IEEE extract fpc instruction | ||
67 | oi 3(%r12),2 # set IEEE fpu flag | ||
68 | .Lchkfpu: | ||
69 | |||
70 | # | ||
71 | # find out if we have the CSP instruction | ||
72 | # | ||
73 | mvc __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13) | ||
74 | la %r0,0 | ||
75 | lr %r1,%r0 | ||
76 | la %r2,4 | ||
77 | csp %r0,%r2 # Test CSP instruction | ||
78 | oi 3(%r12),8 # set CSP flag | ||
79 | .Lchkcsp: | ||
80 | |||
81 | # | ||
82 | # find out if we have the MVPG instruction | ||
83 | # | ||
84 | mvc __LC_PGM_NEW_PSW(8),.Lpcmvpg-.LPG1(%r13) | ||
85 | sr %r0,%r0 | ||
86 | la %r1,0 | ||
87 | la %r2,0 | ||
88 | mvpg %r1,%r2 # Test CSP instruction | ||
89 | oi 3(%r12),16 # set MVPG flag | ||
90 | .Lchkmvpg: | ||
91 | |||
92 | # | ||
93 | # find out if we have the IDTE instruction | ||
94 | # | ||
95 | mvc __LC_PGM_NEW_PSW(8),.Lpcidte-.LPG1(%r13) | ||
96 | .long 0xb2b10000 # store facility list | ||
97 | tm 0xc8,0x08 # check bit for clearing-by-ASCE | ||
98 | bno .Lchkidte-.LPG1(%r13) | ||
99 | lhi %r1,2094 | ||
100 | lhi %r2,0 | ||
101 | .long 0xb98e2001 | ||
102 | oi 3(%r12),0x80 # set IDTE flag | ||
103 | .Lchkidte: | ||
104 | |||
105 | # | ||
106 | # find out if the diag 0x9c is available | ||
107 | # | ||
108 | mvc __LC_PGM_NEW_PSW(8),.Lpcdiag9c-.LPG1(%r13) | ||
109 | stap __LC_CPUID+4 # store cpu address | ||
110 | lh %r1,__LC_CPUID+4 | ||
111 | diag %r1,0,0x9c # test diag 0x9c | ||
112 | oi 2(%r12),1 # set diag9c flag | ||
113 | .Lchkdiag9c: | ||
114 | |||
115 | lpsw .Lentry-.LPG1(13) # jump to _stext in primary-space, | 60 | lpsw .Lentry-.LPG1(13) # jump to _stext in primary-space, |
116 | # virtual and never return ... | 61 | # virtual and never return ... |
117 | .align 8 | 62 | .align 8 |
@@ -132,13 +77,7 @@ startup_continue: | |||
132 | .long 0 # cr13: home space segment table | 77 | .long 0 # cr13: home space segment table |
133 | .long 0xc0000000 # cr14: machine check handling off | 78 | .long 0xc0000000 # cr14: machine check handling off |
134 | .long 0 # cr15: linkage stack operations | 79 | .long 0 # cr15: linkage stack operations |
135 | .Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu | ||
136 | .Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp | ||
137 | .Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg | ||
138 | .Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte | ||
139 | .Lpcdiag9c:.long 0x00080000,0x80000000 + .Lchkdiag9c | ||
140 | .Lmchunk:.long memory_chunk | 80 | .Lmchunk:.long memory_chunk |
141 | .Lmflags:.long machine_flags | ||
142 | .Lbss_bgn: .long __bss_start | 81 | .Lbss_bgn: .long __bss_start |
143 | .Lbss_end: .long _end | 82 | .Lbss_end: .long _end |
144 | .Lparmaddr: .long PARMAREA | 83 | .Lparmaddr: .long PARMAREA |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 79dccd206a6e..9c2c6f7d37e7 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
@@ -125,68 +125,6 @@ startup_continue: | |||
125 | # and create a kernel NSS if the SAVESYS= parm is defined | 125 | # and create a kernel NSS if the SAVESYS= parm is defined |
126 | # | 126 | # |
127 | brasl %r14,startup_init | 127 | brasl %r14,startup_init |
128 | # set program check new psw mask | ||
129 | mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) | ||
130 | larl %r12,machine_flags | ||
131 | # | ||
132 | # find out if we have the MVPG instruction | ||
133 | # | ||
134 | la %r1,0f-.LPG1(%r13) # set program check address | ||
135 | stg %r1,__LC_PGM_NEW_PSW+8 | ||
136 | sgr %r0,%r0 | ||
137 | lghi %r1,0 | ||
138 | lghi %r2,0 | ||
139 | mvpg %r1,%r2 # test MVPG instruction | ||
140 | oi 7(%r12),16 # set MVPG flag | ||
141 | 0: | ||
142 | |||
143 | # | ||
144 | # find out if the diag 0x44 works in 64 bit mode | ||
145 | # | ||
146 | la %r1,0f-.LPG1(%r13) # set program check address | ||
147 | stg %r1,__LC_PGM_NEW_PSW+8 | ||
148 | diag 0,0,0x44 # test diag 0x44 | ||
149 | oi 7(%r12),32 # set diag44 flag | ||
150 | 0: | ||
151 | |||
152 | # | ||
153 | # find out if we have the IDTE instruction | ||
154 | # | ||
155 | la %r1,0f-.LPG1(%r13) # set program check address | ||
156 | stg %r1,__LC_PGM_NEW_PSW+8 | ||
157 | .long 0xb2b10000 # store facility list | ||
158 | tm 0xc8,0x08 # check bit for clearing-by-ASCE | ||
159 | bno 0f-.LPG1(%r13) | ||
160 | lhi %r1,2048 | ||
161 | lhi %r2,0 | ||
162 | .long 0xb98e2001 | ||
163 | oi 7(%r12),0x80 # set IDTE flag | ||
164 | 0: | ||
165 | |||
166 | # | ||
167 | # find out if the diag 0x9c is available | ||
168 | # | ||
169 | la %r1,0f-.LPG1(%r13) # set program check address | ||
170 | stg %r1,__LC_PGM_NEW_PSW+8 | ||
171 | stap __LC_CPUID+4 # store cpu address | ||
172 | lh %r1,__LC_CPUID+4 | ||
173 | diag %r1,0,0x9c # test diag 0x9c | ||
174 | oi 6(%r12),1 # set diag9c flag | ||
175 | 0: | ||
176 | |||
177 | # | ||
178 | # find out if we have the MVCOS instruction | ||
179 | # | ||
180 | la %r1,0f-.LPG1(%r13) # set program check address | ||
181 | stg %r1,__LC_PGM_NEW_PSW+8 | ||
182 | .short 0xc800 # mvcos 0(%r0),0(%r0),%r0 | ||
183 | .short 0x0000 | ||
184 | .short 0x0000 | ||
185 | 0: tm 0x8f,0x13 # special-operation exception? | ||
186 | bno 1f-.LPG1(%r13) # if yes, MVCOS is present | ||
187 | oi 6(%r12),2 # set MVCOS flag | ||
188 | 1: | ||
189 | |||
190 | lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space, | 128 | lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space, |
191 | # virtual and never return ... | 129 | # virtual and never return ... |
192 | .align 16 | 130 | .align 16 |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 024180e25e85..694c6546ce64 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -73,7 +73,7 @@ EXPORT_SYMBOL(uaccess); | |||
73 | unsigned int console_mode = 0; | 73 | unsigned int console_mode = 0; |
74 | unsigned int console_devno = -1; | 74 | unsigned int console_devno = -1; |
75 | unsigned int console_irq = -1; | 75 | unsigned int console_irq = -1; |
76 | unsigned long machine_flags = 0; | 76 | unsigned long machine_flags; |
77 | unsigned long elf_hwcap = 0; | 77 | unsigned long elf_hwcap = 0; |
78 | char elf_platform[ELF_PLATFORM_SIZE]; | 78 | char elf_platform[ELF_PLATFORM_SIZE]; |
79 | 79 | ||
diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h index aaf4b518b940..3a9e458fd8c3 100644 --- a/include/asm-s390/setup.h +++ b/include/asm-s390/setup.h | |||
@@ -59,23 +59,36 @@ extern unsigned int s390_noexec; | |||
59 | */ | 59 | */ |
60 | extern unsigned long machine_flags; | 60 | extern unsigned long machine_flags; |
61 | 61 | ||
62 | #define MACHINE_IS_VM (machine_flags & 1) | 62 | #define MACHINE_FLAG_VM (1UL << 0) |
63 | #define MACHINE_IS_P390 (machine_flags & 4) | 63 | #define MACHINE_FLAG_IEEE (1UL << 1) |
64 | #define MACHINE_HAS_MVPG (machine_flags & 16) | 64 | #define MACHINE_FLAG_P390 (1UL << 2) |
65 | #define MACHINE_IS_KVM (machine_flags & 64) | 65 | #define MACHINE_FLAG_CSP (1UL << 3) |
66 | #define MACHINE_HAS_IDTE (machine_flags & 128) | 66 | #define MACHINE_FLAG_MVPG (1UL << 4) |
67 | #define MACHINE_HAS_DIAG9C (machine_flags & 256) | 67 | #define MACHINE_FLAG_DIAG44 (1UL << 5) |
68 | #define MACHINE_FLAG_IDTE (1UL << 6) | ||
69 | #define MACHINE_FLAG_DIAG9C (1UL << 7) | ||
70 | #define MACHINE_FLAG_MVCOS (1UL << 8) | ||
71 | #define MACHINE_FLAG_KVM (1UL << 9) | ||
72 | |||
73 | #define MACHINE_IS_VM (machine_flags & MACHINE_FLAG_VM) | ||
74 | #define MACHINE_IS_KVM (machine_flags & MACHINE_FLAG_KVM) | ||
75 | #define MACHINE_IS_P390 (machine_flags & MACHINE_FLAG_P390) | ||
76 | #define MACHINE_HAS_DIAG9C (machine_flags & MACHINE_FLAG_DIAG9C) | ||
68 | 77 | ||
69 | #ifndef __s390x__ | 78 | #ifndef __s390x__ |
70 | #define MACHINE_HAS_IEEE (machine_flags & 2) | 79 | #define MACHINE_HAS_IEEE (machine_flags & MACHINE_FLAG_IEEE) |
71 | #define MACHINE_HAS_CSP (machine_flags & 8) | 80 | #define MACHINE_HAS_CSP (machine_flags & MACHINE_FLAG_CSP) |
81 | #define MACHINE_HAS_IDTE (0) | ||
72 | #define MACHINE_HAS_DIAG44 (1) | 82 | #define MACHINE_HAS_DIAG44 (1) |
83 | #define MACHINE_HAS_MVPG (machine_flags & MACHINE_FLAG_MVPG) | ||
73 | #define MACHINE_HAS_MVCOS (0) | 84 | #define MACHINE_HAS_MVCOS (0) |
74 | #else /* __s390x__ */ | 85 | #else /* __s390x__ */ |
75 | #define MACHINE_HAS_IEEE (1) | 86 | #define MACHINE_HAS_IEEE (1) |
76 | #define MACHINE_HAS_CSP (1) | 87 | #define MACHINE_HAS_CSP (1) |
77 | #define MACHINE_HAS_DIAG44 (machine_flags & 32) | 88 | #define MACHINE_HAS_IDTE (machine_flags & MACHINE_FLAG_IDTE) |
78 | #define MACHINE_HAS_MVCOS (machine_flags & 512) | 89 | #define MACHINE_HAS_DIAG44 (machine_flags & MACHINE_FLAG_DIAG44) |
90 | #define MACHINE_HAS_MVPG (1) | ||
91 | #define MACHINE_HAS_MVCOS (machine_flags & MACHINE_FLAG_MVCOS) | ||
79 | #endif /* __s390x__ */ | 92 | #endif /* __s390x__ */ |
80 | 93 | ||
81 | #define MACHINE_HAS_SCLP (!MACHINE_IS_P390) | 94 | #define MACHINE_HAS_SCLP (!MACHINE_IS_P390) |
diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h index 8376b195a1b6..ae89cf2478fc 100644 --- a/include/asm-s390/smp.h +++ b/include/asm-s390/smp.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/lowcore.h> | 19 | #include <asm/lowcore.h> |
20 | #include <asm/sigp.h> | 20 | #include <asm/sigp.h> |
21 | #include <asm/ptrace.h> | 21 | #include <asm/ptrace.h> |
22 | #include <asm/system.h> | ||
22 | 23 | ||
23 | /* | 24 | /* |
24 | s390 specific smp.c headers | 25 | s390 specific smp.c headers |
@@ -53,10 +54,7 @@ extern void machine_power_off_smp(void); | |||
53 | 54 | ||
54 | static inline __u16 hard_smp_processor_id(void) | 55 | static inline __u16 hard_smp_processor_id(void) |
55 | { | 56 | { |
56 | __u16 cpu_address; | 57 | return stap(); |
57 | |||
58 | asm volatile("stap %0" : "=m" (cpu_address)); | ||
59 | return cpu_address; | ||
60 | } | 58 | } |
61 | 59 | ||
62 | /* | 60 | /* |
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h index 79bdbf4b33a7..c819ae25a842 100644 --- a/include/asm-s390/system.h +++ b/include/asm-s390/system.h | |||
@@ -432,6 +432,14 @@ static inline unsigned int stfl(void) | |||
432 | return S390_lowcore.stfl_fac_list; | 432 | return S390_lowcore.stfl_fac_list; |
433 | } | 433 | } |
434 | 434 | ||
435 | static inline unsigned short stap(void) | ||
436 | { | ||
437 | unsigned short cpu_address; | ||
438 | |||
439 | asm volatile("stap %0" : "=m" (cpu_address)); | ||
440 | return cpu_address; | ||
441 | } | ||
442 | |||
435 | extern void (*_machine_restart)(char *command); | 443 | extern void (*_machine_restart)(char *command); |
436 | extern void (*_machine_halt)(void); | 444 | extern void (*_machine_halt)(void); |
437 | extern void (*_machine_power_off)(void); | 445 | extern void (*_machine_power_off)(void); |