diff options
-rw-r--r-- | arch/s390/defconfig | 1 | ||||
-rw-r--r-- | arch/s390/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/s390/kernel/base.S | 150 | ||||
-rw-r--r-- | arch/s390/kernel/early.c | 307 | ||||
-rw-r--r-- | arch/s390/kernel/head31.S | 164 | ||||
-rw-r--r-- | arch/s390/kernel/head64.S | 175 | ||||
-rw-r--r-- | arch/s390/kernel/ipl.c | 15 | ||||
-rw-r--r-- | arch/s390/kernel/reset.S | 90 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 134 | ||||
-rw-r--r-- | drivers/s390/Kconfig | 8 | ||||
-rw-r--r-- | drivers/s390/char/Makefile | 4 | ||||
-rw-r--r-- | drivers/s390/char/sclp.c | 12 | ||||
-rw-r--r-- | drivers/s390/char/sclp.h | 18 | ||||
-rw-r--r-- | drivers/s390/char/sclp_cpi.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp_info.c | 57 | ||||
-rw-r--r-- | drivers/s390/char/sclp_rw.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp_vt220.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 10 | ||||
-rw-r--r-- | include/asm-s390/processor.h | 12 | ||||
-rw-r--r-- | include/asm-s390/reset.h | 3 | ||||
-rw-r--r-- | include/asm-s390/sclp.h | 39 |
21 files changed, 598 insertions, 609 deletions
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index dbe3df4b0dab..7c621b8ef683 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
@@ -433,7 +433,6 @@ CONFIG_TN3270_CONSOLE=y | |||
433 | CONFIG_TN3215=y | 433 | CONFIG_TN3215=y |
434 | CONFIG_TN3215_CONSOLE=y | 434 | CONFIG_TN3215_CONSOLE=y |
435 | CONFIG_CCW_CONSOLE=y | 435 | CONFIG_CCW_CONSOLE=y |
436 | CONFIG_SCLP=y | ||
437 | CONFIG_SCLP_TTY=y | 436 | CONFIG_SCLP_TTY=y |
438 | CONFIG_SCLP_CONSOLE=y | 437 | CONFIG_SCLP_CONSOLE=y |
439 | CONFIG_SCLP_VT220_TTY=y | 438 | CONFIG_SCLP_VT220_TTY=y |
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 2de811a71a39..5492d25d7d69 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | EXTRA_AFLAGS := -traditional | 5 | EXTRA_AFLAGS := -traditional |
6 | 6 | ||
7 | obj-y := bitmap.o traps.o time.o process.o reset.o \ | 7 | obj-y := bitmap.o traps.o time.o process.o base.o early.o \ |
8 | setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ | 8 | setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ |
9 | semaphore.o s390_ext.o debug.o irq.o ipl.o | 9 | semaphore.o s390_ext.o debug.o irq.o ipl.o |
10 | 10 | ||
diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S new file mode 100644 index 000000000000..dc7e5259770f --- /dev/null +++ b/arch/s390/kernel/base.S | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | * arch/s390/kernel/base.S | ||
3 | * | ||
4 | * Copyright IBM Corp. 2006,2007 | ||
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | ||
6 | * Michael Holzheu <holzheu@de.ibm.com> | ||
7 | */ | ||
8 | |||
9 | #include <asm/ptrace.h> | ||
10 | #include <asm/lowcore.h> | ||
11 | |||
12 | #ifdef CONFIG_64BIT | ||
13 | |||
14 | .globl s390_base_mcck_handler | ||
15 | s390_base_mcck_handler: | ||
16 | basr %r13,0 | ||
17 | 0: lg %r15,__LC_PANIC_STACK # load panic stack | ||
18 | aghi %r15,-STACK_FRAME_OVERHEAD | ||
19 | larl %r1,s390_base_mcck_handler_fn | ||
20 | lg %r1,0(%r1) | ||
21 | ltgr %r1,%r1 | ||
22 | jz 1f | ||
23 | basr %r14,%r1 | ||
24 | 1: la %r1,4095 | ||
25 | lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1) | ||
26 | lpswe __LC_MCK_OLD_PSW | ||
27 | |||
28 | .section .bss | ||
29 | .globl s390_base_mcck_handler_fn | ||
30 | s390_base_mcck_handler_fn: | ||
31 | .quad 0 | ||
32 | .previous | ||
33 | |||
34 | .globl s390_base_ext_handler | ||
35 | s390_base_ext_handler: | ||
36 | stmg %r0,%r15,__LC_SAVE_AREA | ||
37 | basr %r13,0 | ||
38 | 0: aghi %r15,-STACK_FRAME_OVERHEAD | ||
39 | larl %r1,s390_base_ext_handler_fn | ||
40 | lg %r1,0(%r1) | ||
41 | ltgr %r1,%r1 | ||
42 | jz 1f | ||
43 | basr %r14,%r1 | ||
44 | 1: lmg %r0,%r15,__LC_SAVE_AREA | ||
45 | ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit | ||
46 | lpswe __LC_EXT_OLD_PSW | ||
47 | |||
48 | .section .bss | ||
49 | .globl s390_base_ext_handler_fn | ||
50 | s390_base_ext_handler_fn: | ||
51 | .quad 0 | ||
52 | .previous | ||
53 | |||
54 | .globl s390_base_pgm_handler | ||
55 | s390_base_pgm_handler: | ||
56 | stmg %r0,%r15,__LC_SAVE_AREA | ||
57 | basr %r13,0 | ||
58 | 0: aghi %r15,-STACK_FRAME_OVERHEAD | ||
59 | larl %r1,s390_base_pgm_handler_fn | ||
60 | lg %r1,0(%r1) | ||
61 | ltgr %r1,%r1 | ||
62 | jz 1f | ||
63 | basr %r14,%r1 | ||
64 | lmg %r0,%r15,__LC_SAVE_AREA | ||
65 | lpswe __LC_PGM_OLD_PSW | ||
66 | 1: lpswe disabled_wait_psw-0b(%r13) | ||
67 | |||
68 | .align 8 | ||
69 | disabled_wait_psw: | ||
70 | .quad 0x0002000180000000,0x0000000000000000 + s390_base_pgm_handler | ||
71 | |||
72 | .section .bss | ||
73 | .globl s390_base_pgm_handler_fn | ||
74 | s390_base_pgm_handler_fn: | ||
75 | .quad 0 | ||
76 | .previous | ||
77 | |||
78 | #else /* CONFIG_64BIT */ | ||
79 | |||
80 | .globl s390_base_mcck_handler | ||
81 | s390_base_mcck_handler: | ||
82 | basr %r13,0 | ||
83 | 0: l %r15,__LC_PANIC_STACK # load panic stack | ||
84 | ahi %r15,-STACK_FRAME_OVERHEAD | ||
85 | l %r1,2f-0b(%r13) | ||
86 | l %r1,0(%r1) | ||
87 | ltr %r1,%r1 | ||
88 | jz 1f | ||
89 | basr %r14,%r1 | ||
90 | 1: lm %r0,%r15,__LC_GPREGS_SAVE_AREA | ||
91 | lpsw __LC_MCK_OLD_PSW | ||
92 | |||
93 | 2: .long s390_base_mcck_handler_fn | ||
94 | |||
95 | .section .bss | ||
96 | .globl s390_base_mcck_handler_fn | ||
97 | s390_base_mcck_handler_fn: | ||
98 | .long 0 | ||
99 | .previous | ||
100 | |||
101 | .globl s390_base_ext_handler | ||
102 | s390_base_ext_handler: | ||
103 | stm %r0,%r15,__LC_SAVE_AREA | ||
104 | basr %r13,0 | ||
105 | 0: ahi %r15,-STACK_FRAME_OVERHEAD | ||
106 | l %r1,2f-0b(%r13) | ||
107 | l %r1,0(%r1) | ||
108 | ltr %r1,%r1 | ||
109 | jz 1f | ||
110 | basr %r14,%r1 | ||
111 | 1: lm %r0,%r15,__LC_SAVE_AREA | ||
112 | ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit | ||
113 | lpsw __LC_EXT_OLD_PSW | ||
114 | |||
115 | 2: .long s390_base_ext_handler_fn | ||
116 | |||
117 | .section .bss | ||
118 | .globl s390_base_ext_handler_fn | ||
119 | s390_base_ext_handler_fn: | ||
120 | .long 0 | ||
121 | .previous | ||
122 | |||
123 | .globl s390_base_pgm_handler | ||
124 | s390_base_pgm_handler: | ||
125 | stm %r0,%r15,__LC_SAVE_AREA | ||
126 | basr %r13,0 | ||
127 | 0: ahi %r15,-STACK_FRAME_OVERHEAD | ||
128 | l %r1,2f-0b(%r13) | ||
129 | l %r1,0(%r1) | ||
130 | ltr %r1,%r1 | ||
131 | jz 1f | ||
132 | basr %r14,%r1 | ||
133 | lm %r0,%r15,__LC_SAVE_AREA | ||
134 | lpsw __LC_PGM_OLD_PSW | ||
135 | |||
136 | 1: lpsw disabled_wait_psw-0b(%r13) | ||
137 | |||
138 | 2: .long s390_base_pgm_handler_fn | ||
139 | |||
140 | disabled_wait_psw: | ||
141 | .align 8 | ||
142 | .long 0x000a0000,0x00000000 + s390_base_pgm_handler | ||
143 | |||
144 | .section .bss | ||
145 | .globl s390_base_pgm_handler_fn | ||
146 | s390_base_pgm_handler_fn: | ||
147 | .long 0 | ||
148 | .previous | ||
149 | |||
150 | #endif /* CONFIG_64BIT */ | ||
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c new file mode 100644 index 000000000000..40dd47970a33 --- /dev/null +++ b/arch/s390/kernel/early.c | |||
@@ -0,0 +1,307 @@ | |||
1 | /* | ||
2 | * arch/s390/kernel/early.c | ||
3 | * | ||
4 | * Copyright IBM Corp. 2007 | ||
5 | * Author(s): Hongjie Yang <hongjie@us.ibm.com>, | ||
6 | * Heiko Carstens <heiko.carstens@de.ibm.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/ctype.h> | ||
13 | #include <linux/lockdep.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/pfn.h> | ||
16 | #include <linux/uaccess.h> | ||
17 | #include <asm/lowcore.h> | ||
18 | #include <asm/processor.h> | ||
19 | #include <asm/sections.h> | ||
20 | #include <asm/setup.h> | ||
21 | #include <asm/cpcmd.h> | ||
22 | #include <asm/sclp.h> | ||
23 | |||
24 | /* | ||
25 | * Create a Kernel NSS if the SAVESYS= parameter is defined | ||
26 | */ | ||
27 | #define DEFSYS_CMD_SIZE 96 | ||
28 | #define SAVESYS_CMD_SIZE 32 | ||
29 | |||
30 | extern int _eshared; | ||
31 | char kernel_nss_name[NSS_NAME_SIZE + 1]; | ||
32 | |||
33 | #ifdef CONFIG_SHARED_KERNEL | ||
34 | static noinline __init void create_kernel_nss(void) | ||
35 | { | ||
36 | unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; | ||
37 | #ifdef CONFIG_BLK_DEV_INITRD | ||
38 | unsigned int sinitrd_pfn, einitrd_pfn; | ||
39 | #endif | ||
40 | int response; | ||
41 | char *savesys_ptr; | ||
42 | char upper_command_line[COMMAND_LINE_SIZE]; | ||
43 | char defsys_cmd[DEFSYS_CMD_SIZE]; | ||
44 | char savesys_cmd[SAVESYS_CMD_SIZE]; | ||
45 | |||
46 | /* Do nothing if we are not running under VM */ | ||
47 | if (!MACHINE_IS_VM) | ||
48 | return; | ||
49 | |||
50 | /* Convert COMMAND_LINE to upper case */ | ||
51 | for (i = 0; i < strlen(COMMAND_LINE); i++) | ||
52 | upper_command_line[i] = toupper(COMMAND_LINE[i]); | ||
53 | |||
54 | savesys_ptr = strstr(upper_command_line, "SAVESYS="); | ||
55 | |||
56 | if (!savesys_ptr) | ||
57 | return; | ||
58 | |||
59 | savesys_ptr += 8; /* Point to the beginning of the NSS name */ | ||
60 | for (i = 0; i < NSS_NAME_SIZE; i++) { | ||
61 | if (savesys_ptr[i] == ' ' || savesys_ptr[i] == '\0') | ||
62 | break; | ||
63 | kernel_nss_name[i] = savesys_ptr[i]; | ||
64 | } | ||
65 | |||
66 | stext_pfn = PFN_DOWN(__pa(&_stext)); | ||
67 | eshared_pfn = PFN_DOWN(__pa(&_eshared)); | ||
68 | end_pfn = PFN_UP(__pa(&_end)); | ||
69 | min_size = end_pfn << 2; | ||
70 | |||
71 | sprintf(defsys_cmd, "DEFSYS %s 00000-%.5X EW %.5X-%.5X SR %.5X-%.5X", | ||
72 | kernel_nss_name, stext_pfn - 1, stext_pfn, eshared_pfn - 1, | ||
73 | eshared_pfn, end_pfn); | ||
74 | |||
75 | #ifdef CONFIG_BLK_DEV_INITRD | ||
76 | if (INITRD_START && INITRD_SIZE) { | ||
77 | sinitrd_pfn = PFN_DOWN(__pa(INITRD_START)); | ||
78 | einitrd_pfn = PFN_UP(__pa(INITRD_START + INITRD_SIZE)); | ||
79 | min_size = einitrd_pfn << 2; | ||
80 | sprintf(defsys_cmd, "%s EW %.5X-%.5X", defsys_cmd, | ||
81 | sinitrd_pfn, einitrd_pfn); | ||
82 | } | ||
83 | #endif | ||
84 | |||
85 | sprintf(defsys_cmd, "%s EW MINSIZE=%.7iK", defsys_cmd, min_size); | ||
86 | sprintf(savesys_cmd, "SAVESYS %s \n IPL %s", | ||
87 | kernel_nss_name, kernel_nss_name); | ||
88 | |||
89 | __cpcmd(defsys_cmd, NULL, 0, &response); | ||
90 | |||
91 | if (response != 0) | ||
92 | return; | ||
93 | |||
94 | __cpcmd(savesys_cmd, NULL, 0, &response); | ||
95 | |||
96 | if (response != strlen(savesys_cmd)) | ||
97 | return; | ||
98 | |||
99 | ipl_flags = IPL_NSS_VALID; | ||
100 | } | ||
101 | |||
102 | #else /* CONFIG_SHARED_KERNEL */ | ||
103 | |||
104 | static inline void create_kernel_nss(void) { } | ||
105 | |||
106 | #endif /* CONFIG_SHARED_KERNEL */ | ||
107 | |||
108 | /* | ||
109 | * Clear bss memory | ||
110 | */ | ||
111 | static noinline __init void clear_bss_section(void) | ||
112 | { | ||
113 | memset(__bss_start, 0, _end - __bss_start); | ||
114 | } | ||
115 | |||
116 | /* | ||
117 | * Initialize storage key for kernel pages | ||
118 | */ | ||
119 | static noinline __init void init_kernel_storage_key(void) | ||
120 | { | ||
121 | unsigned long end_pfn, init_pfn; | ||
122 | |||
123 | end_pfn = PFN_UP(__pa(&_end)); | ||
124 | |||
125 | for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++) | ||
126 | page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY); | ||
127 | } | ||
128 | |||
129 | static noinline __init void detect_machine_type(void) | ||
130 | { | ||
131 | struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data; | ||
132 | |||
133 | asm volatile("stidp %0" : "=m" (S390_lowcore.cpu_data.cpu_id)); | ||
134 | |||
135 | /* Running under z/VM ? */ | ||
136 | if (cpuinfo->cpu_id.version == 0xff) | ||
137 | machine_flags |= 1; | ||
138 | |||
139 | /* Running on a P/390 ? */ | ||
140 | if (cpuinfo->cpu_id.machine == 0x7490) | ||
141 | machine_flags |= 4; | ||
142 | } | ||
143 | |||
144 | static noinline __init int memory_fast_detect(void) | ||
145 | { | ||
146 | |||
147 | unsigned long val0 = 0; | ||
148 | unsigned long val1 = 0xc; | ||
149 | int ret = -ENOSYS; | ||
150 | |||
151 | if (ipl_flags & IPL_NSS_VALID) | ||
152 | return -ENOSYS; | ||
153 | |||
154 | asm volatile( | ||
155 | " diag %1,%2,0x260\n" | ||
156 | "0: lhi %0,0\n" | ||
157 | "1:\n" | ||
158 | EX_TABLE(0b,1b) | ||
159 | : "+d" (ret), "+d" (val0), "+d" (val1) : : "cc"); | ||
160 | |||
161 | if (ret || val0 != val1) | ||
162 | return -ENOSYS; | ||
163 | |||
164 | memory_chunk[0].size = val0; | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | #define ADDR2G (1UL << 31) | ||
169 | |||
170 | static noinline __init unsigned long sclp_memory_detect(void) | ||
171 | { | ||
172 | struct sclp_readinfo_sccb *sccb; | ||
173 | unsigned long long memsize; | ||
174 | |||
175 | sccb = &s390_readinfo_sccb; | ||
176 | |||
177 | if (sccb->header.response_code != 0x10) | ||
178 | return 0; | ||
179 | |||
180 | if (sccb->rnsize) | ||
181 | memsize = sccb->rnsize << 20; | ||
182 | else | ||
183 | memsize = sccb->rnsize2 << 20; | ||
184 | if (sccb->rnmax) | ||
185 | memsize *= sccb->rnmax; | ||
186 | else | ||
187 | memsize *= sccb->rnmax2; | ||
188 | #ifndef CONFIG_64BIT | ||
189 | /* | ||
190 | * Can't deal with more than 2G in 31 bit addressing mode, so | ||
191 | * limit the value in order to avoid strange side effects. | ||
192 | */ | ||
193 | if (memsize > ADDR2G) | ||
194 | memsize = ADDR2G; | ||
195 | #endif | ||
196 | return (unsigned long) memsize; | ||
197 | } | ||
198 | |||
199 | static inline __init unsigned long __tprot(unsigned long addr) | ||
200 | { | ||
201 | int cc = -1; | ||
202 | |||
203 | asm volatile( | ||
204 | " tprot 0(%1),0\n" | ||
205 | "0: ipm %0\n" | ||
206 | " srl %0,28\n" | ||
207 | "1:\n" | ||
208 | EX_TABLE(0b,1b) | ||
209 | : "+d" (cc) : "a" (addr) : "cc"); | ||
210 | return (unsigned long)cc; | ||
211 | } | ||
212 | |||
213 | /* Checking memory in 128KB increments. */ | ||
214 | #define CHUNK_INCR (1UL << 17) | ||
215 | |||
216 | static noinline __init void find_memory_chunks(unsigned long memsize) | ||
217 | { | ||
218 | unsigned long addr = 0, old_addr = 0; | ||
219 | unsigned long old_cc = CHUNK_READ_WRITE; | ||
220 | unsigned long cc; | ||
221 | int chunk = 0; | ||
222 | |||
223 | while (chunk < MEMORY_CHUNKS) { | ||
224 | cc = __tprot(addr); | ||
225 | while (cc == old_cc) { | ||
226 | addr += CHUNK_INCR; | ||
227 | cc = __tprot(addr); | ||
228 | #ifndef CONFIG_64BIT | ||
229 | if (addr == ADDR2G) | ||
230 | break; | ||
231 | #endif | ||
232 | } | ||
233 | |||
234 | if (old_addr != addr && | ||
235 | (old_cc == CHUNK_READ_WRITE || old_cc == CHUNK_READ_ONLY)) { | ||
236 | memory_chunk[chunk].addr = old_addr; | ||
237 | memory_chunk[chunk].size = addr - old_addr; | ||
238 | memory_chunk[chunk].type = old_cc; | ||
239 | chunk++; | ||
240 | } | ||
241 | |||
242 | old_addr = addr; | ||
243 | old_cc = cc; | ||
244 | |||
245 | #ifndef CONFIG_64BIT | ||
246 | if (addr == ADDR2G) | ||
247 | break; | ||
248 | #endif | ||
249 | /* | ||
250 | * Finish memory detection at the first hole, unless | ||
251 | * - we reached the hsa -> skip it. | ||
252 | * - we know there must be more. | ||
253 | */ | ||
254 | if (cc == -1UL && !memsize && old_addr != ADDR2G) | ||
255 | break; | ||
256 | if (memsize && addr >= memsize) | ||
257 | break; | ||
258 | } | ||
259 | } | ||
260 | |||
261 | static __init void early_pgm_check_handler(void) | ||
262 | { | ||
263 | unsigned long addr; | ||
264 | const struct exception_table_entry *fixup; | ||
265 | |||
266 | addr = S390_lowcore.program_old_psw.addr; | ||
267 | fixup = search_exception_tables(addr & PSW_ADDR_INSN); | ||
268 | if (!fixup) | ||
269 | disabled_wait(0); | ||
270 | S390_lowcore.program_old_psw.addr = fixup->fixup | PSW_ADDR_AMODE; | ||
271 | } | ||
272 | |||
273 | static noinline __init void setup_lowcore_early(void) | ||
274 | { | ||
275 | psw_t psw; | ||
276 | |||
277 | psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; | ||
278 | psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_ext_handler; | ||
279 | S390_lowcore.external_new_psw = psw; | ||
280 | psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler; | ||
281 | S390_lowcore.program_new_psw = psw; | ||
282 | s390_base_pgm_handler_fn = early_pgm_check_handler; | ||
283 | } | ||
284 | |||
285 | /* | ||
286 | * Save ipl parameters, clear bss memory, initialize storage keys | ||
287 | * and create a kernel NSS at startup if the SAVESYS= parm is defined | ||
288 | */ | ||
289 | void __init startup_init(void) | ||
290 | { | ||
291 | unsigned long memsize; | ||
292 | |||
293 | ipl_save_parameters(); | ||
294 | clear_bss_section(); | ||
295 | init_kernel_storage_key(); | ||
296 | lockdep_init(); | ||
297 | lockdep_off(); | ||
298 | detect_machine_type(); | ||
299 | create_kernel_nss(); | ||
300 | sort_main_extable(); | ||
301 | setup_lowcore_early(); | ||
302 | sclp_readinfo_early(); | ||
303 | memsize = sclp_memory_detect(); | ||
304 | if (memory_fast_detect() < 0) | ||
305 | find_memory_chunks(memsize); | ||
306 | lockdep_on(); | ||
307 | } | ||
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index b3dcdcdc80c0..453fd3b4edea 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S | |||
@@ -58,145 +58,6 @@ startup_continue: | |||
58 | l %r14,.Lstartup_init-.LPG1(%r13) | 58 | l %r14,.Lstartup_init-.LPG1(%r13) |
59 | basr %r14,%r14 | 59 | basr %r14,%r14 |
60 | 60 | ||
61 | l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word | ||
62 | .Lservicecall: | ||
63 | stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts | ||
64 | |||
65 | stctl %r0, %r0,.Lcr-.LPG1(%r13) # get cr0 | ||
66 | la %r1,0x200 # set bit 22 | ||
67 | o %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1 | ||
68 | st %r1,.Lcr-.LPG1(%r13) | ||
69 | lctl %r0, %r0,.Lcr-.LPG1(%r13) # load modified cr0 | ||
70 | |||
71 | mvc __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw | ||
72 | la %r1, .Lsclph-.LPG1(%r13) | ||
73 | a %r1,__LC_EXT_NEW_PSW+4 # set handler | ||
74 | st %r1,__LC_EXT_NEW_PSW+4 | ||
75 | |||
76 | l %r4,.Lsccbaddr-.LPG1(%r13) # %r4 is our index for sccb stuff | ||
77 | lr %r1,%r4 # our sccb | ||
78 | .insn rre,0xb2200000,%r2,%r1 # service call | ||
79 | ipm %r1 | ||
80 | srl %r1,28 # get cc code | ||
81 | xr %r3, %r3 | ||
82 | chi %r1,3 | ||
83 | be .Lfchunk-.LPG1(%r13) # leave | ||
84 | chi %r1,2 | ||
85 | be .Lservicecall-.LPG1(%r13) | ||
86 | lpsw .Lwaitsclp-.LPG1(%r13) | ||
87 | .Lsclph: | ||
88 | lh %r1,.Lsccbr-.Lsccb(%r4) | ||
89 | chi %r1,0x10 # 0x0010 is the sucess code | ||
90 | je .Lprocsccb # let's process the sccb | ||
91 | chi %r1,0x1f0 | ||
92 | bne .Lfchunk-.LPG1(%r13) # unhandled error code | ||
93 | c %r2, .Lrcp-.LPG1(%r13) # Did we try Read SCP forced | ||
94 | bne .Lfchunk-.LPG1(%r13) # if no, give up | ||
95 | l %r2, .Lrcp2-.LPG1(%r13) # try with Read SCP | ||
96 | b .Lservicecall-.LPG1(%r13) | ||
97 | .Lprocsccb: | ||
98 | lhi %r1,0 | ||
99 | icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0 | ||
100 | jnz .Lscnd | ||
101 | lhi %r1,0x800 # otherwise report 2GB | ||
102 | .Lscnd: | ||
103 | lhi %r3,0x800 # limit reported memory size to 2GB | ||
104 | cr %r1,%r3 | ||
105 | jl .Lno2gb | ||
106 | lr %r1,%r3 | ||
107 | .Lno2gb: | ||
108 | xr %r3,%r3 # same logic | ||
109 | ic %r3,.Lscpa1-.Lsccb(%r4) | ||
110 | chi %r3,0x00 | ||
111 | jne .Lcompmem | ||
112 | l %r3,.Lscpa2-.Lsccb(%r4) | ||
113 | .Lcompmem: | ||
114 | mr %r2,%r1 # mem in MB on 128-bit | ||
115 | l %r1,.Lonemb-.LPG1(%r13) | ||
116 | mr %r2,%r1 # mem size in bytes in %r3 | ||
117 | b .Lfchunk-.LPG1(%r13) | ||
118 | |||
119 | .align 4 | ||
120 | .Linittu: | ||
121 | .long init_thread_union | ||
122 | .Lstartup_init: | ||
123 | .long startup_init | ||
124 | .Lpmask: | ||
125 | .byte 0 | ||
126 | .align 8 | ||
127 | .Lpcext:.long 0x00080000,0x80000000 | ||
128 | .Lcr: | ||
129 | .long 0x00 # place holder for cr0 | ||
130 | .align 8 | ||
131 | .Lwaitsclp: | ||
132 | .long 0x010a0000,0x80000000 + .Lsclph | ||
133 | .Lrcp: | ||
134 | .int 0x00120001 # Read SCP forced code | ||
135 | .Lrcp2: | ||
136 | .int 0x00020001 # Read SCP code | ||
137 | .Lonemb: | ||
138 | .int 0x100000 | ||
139 | .Lfchunk: | ||
140 | |||
141 | # | ||
142 | # find memory chunks. | ||
143 | # | ||
144 | lr %r9,%r3 # end of mem | ||
145 | mvc __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13) | ||
146 | la %r1,1 # test in increments of 128KB | ||
147 | sll %r1,17 | ||
148 | l %r3,.Lmchunk-.LPG1(%r13) # get pointer to memory_chunk array | ||
149 | slr %r4,%r4 # set start of chunk to zero | ||
150 | slr %r5,%r5 # set end of chunk to zero | ||
151 | slr %r6,%r6 # set access code to zero | ||
152 | la %r10,MEMORY_CHUNKS # number of chunks | ||
153 | .Lloop: | ||
154 | tprot 0(%r5),0 # test protection of first byte | ||
155 | ipm %r7 | ||
156 | srl %r7,28 | ||
157 | clr %r6,%r7 # compare cc with last access code | ||
158 | be .Lsame-.LPG1(%r13) | ||
159 | lhi %r8,0 # no program checks | ||
160 | b .Lsavchk-.LPG1(%r13) | ||
161 | .Lsame: | ||
162 | ar %r5,%r1 # add 128KB to end of chunk | ||
163 | bno .Lloop-.LPG1(%r13) # r1 < 0x80000000 -> loop | ||
164 | .Lchkmem: # > 2GB or tprot got a program check | ||
165 | lhi %r8,1 # set program check flag | ||
166 | .Lsavchk: | ||
167 | clr %r4,%r5 # chunk size > 0? | ||
168 | be .Lchkloop-.LPG1(%r13) | ||
169 | st %r4,0(%r3) # store start address of chunk | ||
170 | lr %r0,%r5 | ||
171 | slr %r0,%r4 | ||
172 | st %r0,4(%r3) # store size of chunk | ||
173 | st %r6,8(%r3) # store type of chunk | ||
174 | la %r3,12(%r3) | ||
175 | ahi %r10,-1 # update chunk number | ||
176 | .Lchkloop: | ||
177 | lr %r6,%r7 # set access code to last cc | ||
178 | # we got an exception or we're starting a new | ||
179 | # chunk , we must check if we should | ||
180 | # still try to find valid memory (if we detected | ||
181 | # the amount of available storage), and if we | ||
182 | # have chunks left | ||
183 | xr %r0,%r0 | ||
184 | clr %r0,%r9 # did we detect memory? | ||
185 | je .Ldonemem # if not, leave | ||
186 | chi %r10,0 # do we have chunks left? | ||
187 | je .Ldonemem | ||
188 | chi %r8,1 # program check ? | ||
189 | je .Lpgmchk | ||
190 | lr %r4,%r5 # potential new chunk | ||
191 | alr %r5,%r1 # add 128KB to end of chunk | ||
192 | j .Llpcnt | ||
193 | .Lpgmchk: | ||
194 | alr %r5,%r1 # add 128KB to end of chunk | ||
195 | lr %r4,%r5 # potential new chunk | ||
196 | .Llpcnt: | ||
197 | clr %r5,%r9 # should we go on? | ||
198 | jl .Lloop | ||
199 | .Ldonemem: | ||
200 | l %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags | 61 | l %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags |
201 | # | 62 | # |
202 | # find out if we have an IEEE fpu | 63 | # find out if we have an IEEE fpu |
@@ -273,7 +134,6 @@ startup_continue: | |||
273 | .long 0 # cr15: linkage stack operations | 134 | .long 0 # cr15: linkage stack operations |
274 | .Lduct: .long 0,0,0,0,0,0,0,0 | 135 | .Lduct: .long 0,0,0,0,0,0,0,0 |
275 | .long 0,0,0,0,0,0,0,0 | 136 | .long 0,0,0,0,0,0,0,0 |
276 | .Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem | ||
277 | .Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu | 137 | .Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu |
278 | .Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp | 138 | .Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp |
279 | .Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg | 139 | .Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg |
@@ -284,7 +144,9 @@ startup_continue: | |||
284 | .Lbss_bgn: .long __bss_start | 144 | .Lbss_bgn: .long __bss_start |
285 | .Lbss_end: .long _end | 145 | .Lbss_end: .long _end |
286 | .Lparmaddr: .long PARMAREA | 146 | .Lparmaddr: .long PARMAREA |
287 | .Lsccbaddr: .long .Lsccb | 147 | .Linittu: .long init_thread_union |
148 | .Lstartup_init: | ||
149 | .long startup_init | ||
288 | 150 | ||
289 | .globl ipl_schib | 151 | .globl ipl_schib |
290 | ipl_schib: | 152 | ipl_schib: |
@@ -300,26 +162,6 @@ ipl_devno: | |||
300 | .word 0 | 162 | .word 0 |
301 | 163 | ||
302 | .org 0x12000 | 164 | .org 0x12000 |
303 | .globl s390_readinfo_sccb | ||
304 | s390_readinfo_sccb: | ||
305 | .Lsccb: | ||
306 | .hword 0x1000 # length, one page | ||
307 | .byte 0x00,0x00,0x00 | ||
308 | .byte 0x80 # variable response bit set | ||
309 | .Lsccbr: | ||
310 | .hword 0x00 # response code | ||
311 | .Lscpincr1: | ||
312 | .hword 0x00 | ||
313 | .Lscpa1: | ||
314 | .byte 0x00 | ||
315 | .fill 89,1,0 | ||
316 | .Lscpa2: | ||
317 | .int 0x00 | ||
318 | .Lscpincr2: | ||
319 | .quad 0x00 | ||
320 | .fill 3984,1,0 | ||
321 | .org 0x13000 | ||
322 | |||
323 | #ifdef CONFIG_SHARED_KERNEL | 165 | #ifdef CONFIG_SHARED_KERNEL |
324 | .org 0x100000 | 166 | .org 0x100000 |
325 | #endif | 167 | #endif |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 030a1c95f47c..b8fec4e5c5d4 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
@@ -65,162 +65,6 @@ startup_continue: | |||
65 | brasl %r14,startup_init | 65 | brasl %r14,startup_init |
66 | # set program check new psw mask | 66 | # set program check new psw mask |
67 | mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) | 67 | mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) |
68 | larl %r1,.Lslowmemdetect # set program check address | ||
69 | stg %r1,__LC_PGM_NEW_PSW+8 | ||
70 | lghi %r1,0xc | ||
71 | diag %r0,%r1,0x260 # get memory size of virtual machine | ||
72 | cgr %r0,%r1 # different? -> old detection routine | ||
73 | jne .Lslowmemdetect | ||
74 | larl %r3,ipl_flags | ||
75 | llgt %r3,0(%r3) | ||
76 | chi %r3,4 # ipled from an kernel NSS | ||
77 | je .Lslowmemdetect | ||
78 | aghi %r1,1 # size is one more than end | ||
79 | larl %r2,memory_chunk | ||
80 | stg %r1,8(%r2) # store size of chunk | ||
81 | |||
82 | .Lslowmemdetect: | ||
83 | l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word | ||
84 | .Lservicecall: | ||
85 | stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts | ||
86 | |||
87 | stctg %r0,%r0,.Lcr-.LPG1(%r13) # get cr0 | ||
88 | la %r1,0x200 # set bit 22 | ||
89 | og %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1 | ||
90 | stg %r1,.Lcr-.LPG1(%r13) | ||
91 | lctlg %r0,%r0,.Lcr-.LPG1(%r13) # load modified cr0 | ||
92 | |||
93 | mvc __LC_EXT_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # set postcall psw | ||
94 | larl %r1,.Lsclph | ||
95 | stg %r1,__LC_EXT_NEW_PSW+8 # set handler | ||
96 | |||
97 | larl %r4,.Lsccb # %r4 is our index for sccb stuff | ||
98 | lgr %r1,%r4 # our sccb | ||
99 | .insn rre,0xb2200000,%r2,%r1 # service call | ||
100 | ipm %r1 | ||
101 | srl %r1,28 # get cc code | ||
102 | xr %r3,%r3 | ||
103 | chi %r1,3 | ||
104 | be .Lfchunk-.LPG1(%r13) # leave | ||
105 | chi %r1,2 | ||
106 | be .Lservicecall-.LPG1(%r13) | ||
107 | lpswe .Lwaitsclp-.LPG1(%r13) | ||
108 | .Lsclph: | ||
109 | lh %r1,.Lsccbr-.Lsccb(%r4) | ||
110 | chi %r1,0x10 # 0x0010 is the sucess code | ||
111 | je .Lprocsccb # let's process the sccb | ||
112 | chi %r1,0x1f0 | ||
113 | bne .Lfchunk-.LPG1(%r13) # unhandled error code | ||
114 | c %r2,.Lrcp-.LPG1(%r13) # Did we try Read SCP forced | ||
115 | bne .Lfchunk-.LPG1(%r13) # if no, give up | ||
116 | l %r2,.Lrcp2-.LPG1(%r13) # try with Read SCP | ||
117 | b .Lservicecall-.LPG1(%r13) | ||
118 | .Lprocsccb: | ||
119 | lghi %r1,0 | ||
120 | icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0 | ||
121 | jnz .Lscnd | ||
122 | lg %r1,.Lscpincr2-.Lsccb(%r4) # otherwise use this one | ||
123 | .Lscnd: | ||
124 | xr %r3,%r3 # same logic | ||
125 | ic %r3,.Lscpa1-.Lsccb(%r4) | ||
126 | chi %r3,0x00 | ||
127 | jne .Lcompmem | ||
128 | l %r3,.Lscpa2-.Lsccb(%r4) | ||
129 | .Lcompmem: | ||
130 | mlgr %r2,%r1 # mem in MB on 128-bit | ||
131 | l %r1,.Lonemb-.LPG1(%r13) | ||
132 | mlgr %r2,%r1 # mem size in bytes in %r3 | ||
133 | b .Lfchunk-.LPG1(%r13) | ||
134 | |||
135 | .align 4 | ||
136 | .Lpmask: | ||
137 | .byte 0 | ||
138 | .align 8 | ||
139 | .Lcr: | ||
140 | .quad 0x00 # place holder for cr0 | ||
141 | .Lwaitsclp: | ||
142 | .quad 0x0102000180000000,.Lsclph | ||
143 | .Lrcp: | ||
144 | .int 0x00120001 # Read SCP forced code | ||
145 | .Lrcp2: | ||
146 | .int 0x00020001 # Read SCP code | ||
147 | .Lonemb: | ||
148 | .int 0x100000 | ||
149 | |||
150 | .Lfchunk: | ||
151 | |||
152 | # | ||
153 | # find memory chunks. | ||
154 | # | ||
155 | larl %r9,memory_chunk # skip tprot loop if diag260 | ||
156 | lg %r9,8(%r9) # memory detection was successful | ||
157 | ltgr %r9,%r9 | ||
158 | jne .Ldonemem | ||
159 | |||
160 | lgr %r9,%r3 # end of mem | ||
161 | larl %r1,.Lchkmem # set program check address | ||
162 | stg %r1,__LC_PGM_NEW_PSW+8 | ||
163 | la %r1,1 # test in increments of 128KB | ||
164 | sllg %r1,%r1,17 | ||
165 | larl %r3,memory_chunk | ||
166 | slgr %r4,%r4 # set start of chunk to zero | ||
167 | slgr %r5,%r5 # set end of chunk to zero | ||
168 | slr %r6,%r6 # set access code to zero | ||
169 | la %r10,MEMORY_CHUNKS # number of chunks | ||
170 | .Lloop: | ||
171 | tprot 0(%r5),0 # test protection of first byte | ||
172 | ipm %r7 | ||
173 | srl %r7,28 | ||
174 | clr %r6,%r7 # compare cc with last access code | ||
175 | je .Lsame | ||
176 | lghi %r8,0 # no program checks | ||
177 | j .Lsavchk | ||
178 | .Lsame: | ||
179 | algr %r5,%r1 # add 128KB to end of chunk | ||
180 | # no need to check here, | ||
181 | brc 12,.Lloop # this is the same chunk | ||
182 | .Lchkmem: # > 16EB or tprot got a program check | ||
183 | lghi %r8,1 # set program check flag | ||
184 | .Lsavchk: | ||
185 | clgr %r4,%r5 # chunk size > 0? | ||
186 | je .Lchkloop | ||
187 | stg %r4,0(%r3) # store start address of chunk | ||
188 | lgr %r0,%r5 | ||
189 | slgr %r0,%r4 | ||
190 | stg %r0,8(%r3) # store size of chunk | ||
191 | st %r6,20(%r3) # store type of chunk | ||
192 | la %r3,24(%r3) | ||
193 | ahi %r10,-1 # update chunk number | ||
194 | .Lchkloop: | ||
195 | lr %r6,%r7 # set access code to last cc | ||
196 | # we got an exception or we're starting a new | ||
197 | # chunk , we must check if we should | ||
198 | # still try to find valid memory (if we detected | ||
199 | # the amount of available storage), and if we | ||
200 | # have chunks left | ||
201 | lghi %r4,1 | ||
202 | sllg %r4,%r4,31 | ||
203 | clgr %r5,%r4 | ||
204 | je .Lhsaskip | ||
205 | xr %r0, %r0 | ||
206 | clgr %r0, %r9 # did we detect memory? | ||
207 | je .Ldonemem # if not, leave | ||
208 | chi %r10, 0 # do we have chunks left? | ||
209 | je .Ldonemem | ||
210 | .Lhsaskip: | ||
211 | chi %r8,1 # program check ? | ||
212 | je .Lpgmchk | ||
213 | lgr %r4,%r5 # potential new chunk | ||
214 | algr %r5,%r1 # add 128KB to end of chunk | ||
215 | j .Llpcnt | ||
216 | .Lpgmchk: | ||
217 | algr %r5,%r1 # add 128KB to end of chunk | ||
218 | lgr %r4,%r5 # potential new chunk | ||
219 | .Llpcnt: | ||
220 | clgr %r5,%r9 # should we go on? | ||
221 | jl .Lloop | ||
222 | .Ldonemem: | ||
223 | |||
224 | larl %r12,machine_flags | 68 | larl %r12,machine_flags |
225 | # | 69 | # |
226 | # find out if we have the MVPG instruction | 70 | # find out if we have the MVPG instruction |
@@ -324,25 +168,6 @@ ipl_devno: | |||
324 | .word 0 | 168 | .word 0 |
325 | 169 | ||
326 | .org 0x12000 | 170 | .org 0x12000 |
327 | .globl s390_readinfo_sccb | ||
328 | s390_readinfo_sccb: | ||
329 | .Lsccb: | ||
330 | .hword 0x1000 # length, one page | ||
331 | .byte 0x00,0x00,0x00 | ||
332 | .byte 0x80 # variable response bit set | ||
333 | .Lsccbr: | ||
334 | .hword 0x00 # response code | ||
335 | .Lscpincr1: | ||
336 | .hword 0x00 | ||
337 | .Lscpa1: | ||
338 | .byte 0x00 | ||
339 | .fill 89,1,0 | ||
340 | .Lscpa2: | ||
341 | .int 0x00 | ||
342 | .Lscpincr2: | ||
343 | .quad 0x00 | ||
344 | .fill 3984,1,0 | ||
345 | .org 0x13000 | ||
346 | 171 | ||
347 | #ifdef CONFIG_SHARED_KERNEL | 172 | #ifdef CONFIG_SHARED_KERNEL |
348 | .org 0x100000 | 173 | .org 0x100000 |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 13eacce62011..052259530651 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -20,14 +20,13 @@ | |||
20 | #include <asm/cio.h> | 20 | #include <asm/cio.h> |
21 | #include <asm/ebcdic.h> | 21 | #include <asm/ebcdic.h> |
22 | #include <asm/reset.h> | 22 | #include <asm/reset.h> |
23 | #include <asm/sclp.h> | ||
23 | 24 | ||
24 | #define IPL_PARM_BLOCK_VERSION 0 | 25 | #define IPL_PARM_BLOCK_VERSION 0 |
25 | #define LOADPARM_LEN 8 | ||
26 | 26 | ||
27 | extern char s390_readinfo_sccb[]; | 27 | #define SCCB_VALID (s390_readinfo_sccb.header.response_code == 0x10) |
28 | #define SCCB_VALID (*((__u16*)&s390_readinfo_sccb[6]) == 0x0010) | 28 | #define SCCB_LOADPARM (&s390_readinfo_sccb.loadparm) |
29 | #define SCCB_LOADPARM (&s390_readinfo_sccb[24]) | 29 | #define SCCB_FLAG (s390_readinfo_sccb.flags) |
30 | #define SCCB_FLAG (s390_readinfo_sccb[91]) | ||
31 | 30 | ||
32 | enum ipl_type { | 31 | enum ipl_type { |
33 | IPL_TYPE_NONE = 1, | 32 | IPL_TYPE_NONE = 1, |
@@ -1080,8 +1079,6 @@ static void do_reset_calls(void) | |||
1080 | reset->fn(); | 1079 | reset->fn(); |
1081 | } | 1080 | } |
1082 | 1081 | ||
1083 | extern void reset_mcck_handler(void); | ||
1084 | extern void reset_pgm_handler(void); | ||
1085 | extern __u32 dump_prefix_page; | 1082 | extern __u32 dump_prefix_page; |
1086 | 1083 | ||
1087 | void s390_reset_system(void) | 1084 | void s390_reset_system(void) |
@@ -1105,12 +1102,12 @@ void s390_reset_system(void) | |||
1105 | /* Set new machine check handler */ | 1102 | /* Set new machine check handler */ |
1106 | S390_lowcore.mcck_new_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK; | 1103 | S390_lowcore.mcck_new_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK; |
1107 | S390_lowcore.mcck_new_psw.addr = | 1104 | S390_lowcore.mcck_new_psw.addr = |
1108 | PSW_ADDR_AMODE | (unsigned long) &reset_mcck_handler; | 1105 | PSW_ADDR_AMODE | (unsigned long) s390_base_mcck_handler; |
1109 | 1106 | ||
1110 | /* Set new program check handler */ | 1107 | /* Set new program check handler */ |
1111 | S390_lowcore.program_new_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK; | 1108 | S390_lowcore.program_new_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK; |
1112 | S390_lowcore.program_new_psw.addr = | 1109 | S390_lowcore.program_new_psw.addr = |
1113 | PSW_ADDR_AMODE | (unsigned long) &reset_pgm_handler; | 1110 | PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler; |
1114 | 1111 | ||
1115 | do_reset_calls(); | 1112 | do_reset_calls(); |
1116 | } | 1113 | } |
diff --git a/arch/s390/kernel/reset.S b/arch/s390/kernel/reset.S deleted file mode 100644 index 8a87355161fa..000000000000 --- a/arch/s390/kernel/reset.S +++ /dev/null | |||
@@ -1,90 +0,0 @@ | |||
1 | /* | ||
2 | * arch/s390/kernel/reset.S | ||
3 | * | ||
4 | * Copyright (C) IBM Corp. 2006 | ||
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | ||
6 | * Michael Holzheu <holzheu@de.ibm.com> | ||
7 | */ | ||
8 | |||
9 | #include <asm/ptrace.h> | ||
10 | #include <asm/lowcore.h> | ||
11 | |||
12 | #ifdef CONFIG_64BIT | ||
13 | |||
14 | .globl reset_mcck_handler | ||
15 | reset_mcck_handler: | ||
16 | basr %r13,0 | ||
17 | 0: lg %r15,__LC_PANIC_STACK # load panic stack | ||
18 | aghi %r15,-STACK_FRAME_OVERHEAD | ||
19 | lg %r1,s390_reset_mcck_handler-0b(%r13) | ||
20 | ltgr %r1,%r1 | ||
21 | jz 1f | ||
22 | basr %r14,%r1 | ||
23 | 1: la %r1,4095 | ||
24 | lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1) | ||
25 | lpswe __LC_MCK_OLD_PSW | ||
26 | |||
27 | .globl s390_reset_mcck_handler | ||
28 | s390_reset_mcck_handler: | ||
29 | .quad 0 | ||
30 | |||
31 | .globl reset_pgm_handler | ||
32 | reset_pgm_handler: | ||
33 | stmg %r0,%r15,__LC_SAVE_AREA | ||
34 | basr %r13,0 | ||
35 | 0: lg %r15,__LC_PANIC_STACK # load panic stack | ||
36 | aghi %r15,-STACK_FRAME_OVERHEAD | ||
37 | lg %r1,s390_reset_pgm_handler-0b(%r13) | ||
38 | ltgr %r1,%r1 | ||
39 | jz 1f | ||
40 | basr %r14,%r1 | ||
41 | lmg %r0,%r15,__LC_SAVE_AREA | ||
42 | lpswe __LC_PGM_OLD_PSW | ||
43 | 1: lpswe disabled_wait_psw-0b(%r13) | ||
44 | .globl s390_reset_pgm_handler | ||
45 | s390_reset_pgm_handler: | ||
46 | .quad 0 | ||
47 | .align 8 | ||
48 | disabled_wait_psw: | ||
49 | .quad 0x0002000180000000,0x0000000000000000 + reset_pgm_handler | ||
50 | |||
51 | #else /* CONFIG_64BIT */ | ||
52 | |||
53 | .globl reset_mcck_handler | ||
54 | reset_mcck_handler: | ||
55 | basr %r13,0 | ||
56 | 0: l %r15,__LC_PANIC_STACK # load panic stack | ||
57 | ahi %r15,-STACK_FRAME_OVERHEAD | ||
58 | l %r1,s390_reset_mcck_handler-0b(%r13) | ||
59 | ltr %r1,%r1 | ||
60 | jz 1f | ||
61 | basr %r14,%r1 | ||
62 | 1: lm %r0,%r15,__LC_GPREGS_SAVE_AREA | ||
63 | lpsw __LC_MCK_OLD_PSW | ||
64 | |||
65 | .globl s390_reset_mcck_handler | ||
66 | s390_reset_mcck_handler: | ||
67 | .long 0 | ||
68 | |||
69 | .globl reset_pgm_handler | ||
70 | reset_pgm_handler: | ||
71 | stm %r0,%r15,__LC_SAVE_AREA | ||
72 | basr %r13,0 | ||
73 | 0: l %r15,__LC_PANIC_STACK # load panic stack | ||
74 | ahi %r15,-STACK_FRAME_OVERHEAD | ||
75 | l %r1,s390_reset_pgm_handler-0b(%r13) | ||
76 | ltr %r1,%r1 | ||
77 | jz 1f | ||
78 | basr %r14,%r1 | ||
79 | lm %r0,%r15,__LC_SAVE_AREA | ||
80 | lpsw __LC_PGM_OLD_PSW | ||
81 | |||
82 | 1: lpsw disabled_wait_psw-0b(%r13) | ||
83 | .globl s390_reset_pgm_handler | ||
84 | s390_reset_pgm_handler: | ||
85 | .long 0 | ||
86 | disabled_wait_psw: | ||
87 | .align 8 | ||
88 | .long 0x000a0000,0x00000000 + reset_pgm_handler | ||
89 | |||
90 | #endif /* CONFIG_64BIT */ | ||
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 2fa866f6f711..f73a11528217 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -284,140 +284,6 @@ static void __init conmode_default(void) | |||
284 | } | 284 | } |
285 | } | 285 | } |
286 | 286 | ||
287 | /* | ||
288 | * Create a Kernel NSS if the SAVESYS= parameter is defined | ||
289 | */ | ||
290 | #define DEFSYS_CMD_SIZE 96 | ||
291 | #define SAVESYS_CMD_SIZE 32 | ||
292 | |||
293 | extern int _eshared; | ||
294 | char kernel_nss_name[NSS_NAME_SIZE + 1]; | ||
295 | |||
296 | #ifdef CONFIG_SHARED_KERNEL | ||
297 | static __init void create_kernel_nss(void) | ||
298 | { | ||
299 | unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; | ||
300 | #ifdef CONFIG_BLK_DEV_INITRD | ||
301 | unsigned int sinitrd_pfn, einitrd_pfn; | ||
302 | #endif | ||
303 | int response; | ||
304 | char *savesys_ptr; | ||
305 | char upper_command_line[COMMAND_LINE_SIZE]; | ||
306 | char defsys_cmd[DEFSYS_CMD_SIZE]; | ||
307 | char savesys_cmd[SAVESYS_CMD_SIZE]; | ||
308 | |||
309 | /* Do nothing if we are not running under VM */ | ||
310 | if (!MACHINE_IS_VM) | ||
311 | return; | ||
312 | |||
313 | /* Convert COMMAND_LINE to upper case */ | ||
314 | for (i = 0; i < strlen(COMMAND_LINE); i++) | ||
315 | upper_command_line[i] = toupper(COMMAND_LINE[i]); | ||
316 | |||
317 | savesys_ptr = strstr(upper_command_line, "SAVESYS="); | ||
318 | |||
319 | if (!savesys_ptr) | ||
320 | return; | ||
321 | |||
322 | savesys_ptr += 8; /* Point to the beginning of the NSS name */ | ||
323 | for (i = 0; i < NSS_NAME_SIZE; i++) { | ||
324 | if (savesys_ptr[i] == ' ' || savesys_ptr[i] == '\0') | ||
325 | break; | ||
326 | kernel_nss_name[i] = savesys_ptr[i]; | ||
327 | } | ||
328 | |||
329 | stext_pfn = PFN_DOWN(__pa(&_stext)); | ||
330 | eshared_pfn = PFN_DOWN(__pa(&_eshared)); | ||
331 | end_pfn = PFN_UP(__pa(&_end)); | ||
332 | min_size = end_pfn << 2; | ||
333 | |||
334 | sprintf(defsys_cmd, "DEFSYS %s 00000-%.5X EW %.5X-%.5X SR %.5X-%.5X", | ||
335 | kernel_nss_name, stext_pfn - 1, stext_pfn, eshared_pfn - 1, | ||
336 | eshared_pfn, end_pfn); | ||
337 | |||
338 | #ifdef CONFIG_BLK_DEV_INITRD | ||
339 | if (INITRD_START && INITRD_SIZE) { | ||
340 | sinitrd_pfn = PFN_DOWN(__pa(INITRD_START)); | ||
341 | einitrd_pfn = PFN_UP(__pa(INITRD_START + INITRD_SIZE)); | ||
342 | min_size = einitrd_pfn << 2; | ||
343 | sprintf(defsys_cmd, "%s EW %.5X-%.5X", defsys_cmd, | ||
344 | sinitrd_pfn, einitrd_pfn); | ||
345 | } | ||
346 | #endif | ||
347 | |||
348 | sprintf(defsys_cmd, "%s EW MINSIZE=%.7iK", defsys_cmd, min_size); | ||
349 | sprintf(savesys_cmd, "SAVESYS %s \n IPL %s", | ||
350 | kernel_nss_name, kernel_nss_name); | ||
351 | |||
352 | __cpcmd(defsys_cmd, NULL, 0, &response); | ||
353 | |||
354 | if (response != 0) | ||
355 | return; | ||
356 | |||
357 | __cpcmd(savesys_cmd, NULL, 0, &response); | ||
358 | |||
359 | if (response != strlen(savesys_cmd)) | ||
360 | return; | ||
361 | |||
362 | ipl_flags = IPL_NSS_VALID; | ||
363 | } | ||
364 | |||
365 | #else /* CONFIG_SHARED_KERNEL */ | ||
366 | |||
367 | static inline void create_kernel_nss(void) { } | ||
368 | |||
369 | #endif /* CONFIG_SHARED_KERNEL */ | ||
370 | |||
371 | /* | ||
372 | * Clear bss memory | ||
373 | */ | ||
374 | static __init void clear_bss_section(void) | ||
375 | { | ||
376 | memset(__bss_start, 0, _end - __bss_start); | ||
377 | } | ||
378 | |||
379 | /* | ||
380 | * Initialize storage key for kernel pages | ||
381 | */ | ||
382 | static __init void init_kernel_storage_key(void) | ||
383 | { | ||
384 | unsigned long end_pfn, init_pfn; | ||
385 | |||
386 | end_pfn = PFN_UP(__pa(&_end)); | ||
387 | |||
388 | for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++) | ||
389 | page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY); | ||
390 | } | ||
391 | |||
392 | static __init void detect_machine_type(void) | ||
393 | { | ||
394 | struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data; | ||
395 | |||
396 | asm volatile("stidp %0" : "=m" (S390_lowcore.cpu_data.cpu_id)); | ||
397 | |||
398 | /* Running under z/VM ? */ | ||
399 | if (cpuinfo->cpu_id.version == 0xff) | ||
400 | machine_flags |= 1; | ||
401 | |||
402 | /* Running on a P/390 ? */ | ||
403 | if (cpuinfo->cpu_id.machine == 0x7490) | ||
404 | machine_flags |= 4; | ||
405 | } | ||
406 | |||
407 | /* | ||
408 | * Save ipl parameters, clear bss memory, initialize storage keys | ||
409 | * and create a kernel NSS at startup if the SAVESYS= parm is defined | ||
410 | */ | ||
411 | void __init startup_init(void) | ||
412 | { | ||
413 | ipl_save_parameters(); | ||
414 | clear_bss_section(); | ||
415 | init_kernel_storage_key(); | ||
416 | lockdep_init(); | ||
417 | detect_machine_type(); | ||
418 | create_kernel_nss(); | ||
419 | } | ||
420 | |||
421 | #ifdef CONFIG_SMP | 287 | #ifdef CONFIG_SMP |
422 | void (*_machine_restart)(char *command) = machine_restart_smp; | 288 | void (*_machine_restart)(char *command) = machine_restart_smp; |
423 | void (*_machine_halt)(void) = machine_halt_smp; | 289 | void (*_machine_halt)(void) = machine_halt_smp; |
diff --git a/drivers/s390/Kconfig b/drivers/s390/Kconfig index ae89b9b88743..165af398fdea 100644 --- a/drivers/s390/Kconfig +++ b/drivers/s390/Kconfig | |||
@@ -103,14 +103,8 @@ config CCW_CONSOLE | |||
103 | depends on TN3215_CONSOLE || TN3270_CONSOLE | 103 | depends on TN3215_CONSOLE || TN3270_CONSOLE |
104 | default y | 104 | default y |
105 | 105 | ||
106 | config SCLP | ||
107 | bool "Support for SCLP" | ||
108 | help | ||
109 | Include support for the SCLP interface to the service element. | ||
110 | |||
111 | config SCLP_TTY | 106 | config SCLP_TTY |
112 | bool "Support for SCLP line mode terminal" | 107 | bool "Support for SCLP line mode terminal" |
113 | depends on SCLP | ||
114 | help | 108 | help |
115 | Include support for IBM SCLP line-mode terminals. | 109 | Include support for IBM SCLP line-mode terminals. |
116 | 110 | ||
@@ -123,7 +117,6 @@ config SCLP_CONSOLE | |||
123 | 117 | ||
124 | config SCLP_VT220_TTY | 118 | config SCLP_VT220_TTY |
125 | bool "Support for SCLP VT220-compatible terminal" | 119 | bool "Support for SCLP VT220-compatible terminal" |
126 | depends on SCLP | ||
127 | help | 120 | help |
128 | Include support for an IBM SCLP VT220-compatible terminal. | 121 | Include support for an IBM SCLP VT220-compatible terminal. |
129 | 122 | ||
@@ -136,7 +129,6 @@ config SCLP_VT220_CONSOLE | |||
136 | 129 | ||
137 | config SCLP_CPI | 130 | config SCLP_CPI |
138 | tristate "Control-Program Identification" | 131 | tristate "Control-Program Identification" |
139 | depends on SCLP | ||
140 | help | 132 | help |
141 | This option enables the hardware console interface for system | 133 | This option enables the hardware console interface for system |
142 | identification. This is commonly used for workload management and | 134 | identification. This is commonly used for workload management and |
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index c3e97b4fc186..293e667b50f2 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile | |||
@@ -2,7 +2,8 @@ | |||
2 | # S/390 character devices | 2 | # S/390 character devices |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += ctrlchar.o keyboard.o defkeymap.o | 5 | obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \ |
6 | sclp_info.o | ||
6 | 7 | ||
7 | obj-$(CONFIG_TN3270) += raw3270.o | 8 | obj-$(CONFIG_TN3270) += raw3270.o |
8 | obj-$(CONFIG_TN3270_CONSOLE) += con3270.o | 9 | obj-$(CONFIG_TN3270_CONSOLE) += con3270.o |
@@ -11,7 +12,6 @@ obj-$(CONFIG_TN3270_FS) += fs3270.o | |||
11 | 12 | ||
12 | obj-$(CONFIG_TN3215) += con3215.o | 13 | obj-$(CONFIG_TN3215) += con3215.o |
13 | 14 | ||
14 | obj-$(CONFIG_SCLP) += sclp.o sclp_rw.o sclp_quiesce.o | ||
15 | obj-$(CONFIG_SCLP_TTY) += sclp_tty.o | 15 | obj-$(CONFIG_SCLP_TTY) += sclp_tty.o |
16 | obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o | 16 | obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o |
17 | obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o | 17 | obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o |
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index c1dd19bb7bf8..6a83e2d722a8 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c | |||
@@ -96,8 +96,8 @@ static int sclp_init_mask(int calculate); | |||
96 | static int sclp_init(void); | 96 | static int sclp_init(void); |
97 | 97 | ||
98 | /* Perform service call. Return 0 on success, non-zero otherwise. */ | 98 | /* Perform service call. Return 0 on success, non-zero otherwise. */ |
99 | static int | 99 | int |
100 | service_call(sclp_cmdw_t command, void *sccb) | 100 | sclp_service_call(sclp_cmdw_t command, void *sccb) |
101 | { | 101 | { |
102 | int cc; | 102 | int cc; |
103 | 103 | ||
@@ -173,7 +173,7 @@ __sclp_start_request(struct sclp_req *req) | |||
173 | if (sclp_running_state != sclp_running_state_idle) | 173 | if (sclp_running_state != sclp_running_state_idle) |
174 | return 0; | 174 | return 0; |
175 | del_timer(&sclp_request_timer); | 175 | del_timer(&sclp_request_timer); |
176 | rc = service_call(req->command, req->sccb); | 176 | rc = sclp_service_call(req->command, req->sccb); |
177 | req->start_count++; | 177 | req->start_count++; |
178 | 178 | ||
179 | if (rc == 0) { | 179 | if (rc == 0) { |
@@ -325,7 +325,7 @@ __sclp_make_read_req(void) | |||
325 | sccb = (struct sccb_header *) sclp_read_sccb; | 325 | sccb = (struct sccb_header *) sclp_read_sccb; |
326 | clear_page(sccb); | 326 | clear_page(sccb); |
327 | memset(&sclp_read_req, 0, sizeof(struct sclp_req)); | 327 | memset(&sclp_read_req, 0, sizeof(struct sclp_req)); |
328 | sclp_read_req.command = SCLP_CMDW_READDATA; | 328 | sclp_read_req.command = SCLP_CMDW_READ_EVENT_DATA; |
329 | sclp_read_req.status = SCLP_REQ_QUEUED; | 329 | sclp_read_req.status = SCLP_REQ_QUEUED; |
330 | sclp_read_req.start_count = 0; | 330 | sclp_read_req.start_count = 0; |
331 | sclp_read_req.callback = sclp_read_cb; | 331 | sclp_read_req.callback = sclp_read_cb; |
@@ -628,7 +628,7 @@ __sclp_make_init_req(u32 receive_mask, u32 send_mask) | |||
628 | sccb = (struct init_sccb *) sclp_init_sccb; | 628 | sccb = (struct init_sccb *) sclp_init_sccb; |
629 | clear_page(sccb); | 629 | clear_page(sccb); |
630 | memset(&sclp_init_req, 0, sizeof(struct sclp_req)); | 630 | memset(&sclp_init_req, 0, sizeof(struct sclp_req)); |
631 | sclp_init_req.command = SCLP_CMDW_WRITEMASK; | 631 | sclp_init_req.command = SCLP_CMDW_WRITE_EVENT_MASK; |
632 | sclp_init_req.status = SCLP_REQ_FILLED; | 632 | sclp_init_req.status = SCLP_REQ_FILLED; |
633 | sclp_init_req.start_count = 0; | 633 | sclp_init_req.start_count = 0; |
634 | sclp_init_req.callback = NULL; | 634 | sclp_init_req.callback = NULL; |
@@ -831,7 +831,7 @@ sclp_check_interface(void) | |||
831 | for (retry = 0; retry <= SCLP_INIT_RETRY; retry++) { | 831 | for (retry = 0; retry <= SCLP_INIT_RETRY; retry++) { |
832 | __sclp_make_init_req(0, 0); | 832 | __sclp_make_init_req(0, 0); |
833 | sccb = (struct init_sccb *) sclp_init_req.sccb; | 833 | sccb = (struct init_sccb *) sclp_init_req.sccb; |
834 | rc = service_call(sclp_init_req.command, sccb); | 834 | rc = sclp_service_call(sclp_init_req.command, sccb); |
835 | if (rc == -EIO) | 835 | if (rc == -EIO) |
836 | break; | 836 | break; |
837 | sclp_init_req.status = SCLP_REQ_RUNNING; | 837 | sclp_init_req.status = SCLP_REQ_RUNNING; |
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index 2c71d6ee7b5b..7d29ab45a6ed 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h | |||
@@ -12,7 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <linux/list.h> | 14 | #include <linux/list.h> |
15 | 15 | #include <asm/sclp.h> | |
16 | #include <asm/ebcdic.h> | 16 | #include <asm/ebcdic.h> |
17 | 17 | ||
18 | /* maximum number of pages concerning our own memory management */ | 18 | /* maximum number of pages concerning our own memory management */ |
@@ -49,9 +49,11 @@ | |||
49 | 49 | ||
50 | typedef unsigned int sclp_cmdw_t; | 50 | typedef unsigned int sclp_cmdw_t; |
51 | 51 | ||
52 | #define SCLP_CMDW_READDATA 0x00770005 | 52 | #define SCLP_CMDW_READ_EVENT_DATA 0x00770005 |
53 | #define SCLP_CMDW_WRITEDATA 0x00760005 | 53 | #define SCLP_CMDW_WRITE_EVENT_DATA 0x00760005 |
54 | #define SCLP_CMDW_WRITEMASK 0x00780005 | 54 | #define SCLP_CMDW_WRITE_EVENT_MASK 0x00780005 |
55 | #define SCLP_CMDW_READ_SCP_INFO 0x00020001 | ||
56 | #define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001 | ||
55 | 57 | ||
56 | #define GDS_ID_MDSMU 0x1310 | 58 | #define GDS_ID_MDSMU 0x1310 |
57 | #define GDS_ID_MDSRouteInfo 0x1311 | 59 | #define GDS_ID_MDSRouteInfo 0x1311 |
@@ -66,13 +68,6 @@ typedef unsigned int sclp_cmdw_t; | |||
66 | 68 | ||
67 | typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */ | 69 | typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */ |
68 | 70 | ||
69 | struct sccb_header { | ||
70 | u16 length; | ||
71 | u8 function_code; | ||
72 | u8 control_mask[3]; | ||
73 | u16 response_code; | ||
74 | } __attribute__((packed)); | ||
75 | |||
76 | struct gds_subvector { | 71 | struct gds_subvector { |
77 | u8 length; | 72 | u8 length; |
78 | u8 key; | 73 | u8 key; |
@@ -131,6 +126,7 @@ void sclp_unregister(struct sclp_register *reg); | |||
131 | int sclp_remove_processed(struct sccb_header *sccb); | 126 | int sclp_remove_processed(struct sccb_header *sccb); |
132 | int sclp_deactivate(void); | 127 | int sclp_deactivate(void); |
133 | int sclp_reactivate(void); | 128 | int sclp_reactivate(void); |
129 | int sclp_service_call(sclp_cmdw_t command, void *sccb); | ||
134 | 130 | ||
135 | /* useful inlines */ | 131 | /* useful inlines */ |
136 | 132 | ||
diff --git a/drivers/s390/char/sclp_cpi.c b/drivers/s390/char/sclp_cpi.c index 4f873ae148b7..65aa2c85737f 100644 --- a/drivers/s390/char/sclp_cpi.c +++ b/drivers/s390/char/sclp_cpi.c | |||
@@ -169,7 +169,7 @@ cpi_prepare_req(void) | |||
169 | } | 169 | } |
170 | 170 | ||
171 | /* prepare request data structure presented to SCLP driver */ | 171 | /* prepare request data structure presented to SCLP driver */ |
172 | req->command = SCLP_CMDW_WRITEDATA; | 172 | req->command = SCLP_CMDW_WRITE_EVENT_DATA; |
173 | req->sccb = sccb; | 173 | req->sccb = sccb; |
174 | req->status = SCLP_REQ_FILLED; | 174 | req->status = SCLP_REQ_FILLED; |
175 | req->callback = cpi_callback; | 175 | req->callback = cpi_callback; |
diff --git a/drivers/s390/char/sclp_info.c b/drivers/s390/char/sclp_info.c new file mode 100644 index 000000000000..7bcbe643b087 --- /dev/null +++ b/drivers/s390/char/sclp_info.c | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * drivers/s390/char/sclp_info.c | ||
3 | * | ||
4 | * Copyright IBM Corp. 2007 | ||
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #include <linux/init.h> | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/string.h> | ||
11 | #include <asm/sclp.h> | ||
12 | #include "sclp.h" | ||
13 | |||
14 | struct sclp_readinfo_sccb s390_readinfo_sccb; | ||
15 | |||
16 | void __init sclp_readinfo_early(void) | ||
17 | { | ||
18 | sclp_cmdw_t command; | ||
19 | struct sccb_header *sccb; | ||
20 | int ret; | ||
21 | |||
22 | __ctl_set_bit(0, 9); /* enable service signal subclass mask */ | ||
23 | |||
24 | sccb = &s390_readinfo_sccb.header; | ||
25 | command = SCLP_CMDW_READ_SCP_INFO_FORCED; | ||
26 | while (1) { | ||
27 | u16 response; | ||
28 | |||
29 | memset(&s390_readinfo_sccb, 0, sizeof(s390_readinfo_sccb)); | ||
30 | sccb->length = sizeof(s390_readinfo_sccb); | ||
31 | sccb->control_mask[2] = 0x80; | ||
32 | |||
33 | ret = sclp_service_call(command, &s390_readinfo_sccb); | ||
34 | |||
35 | if (ret == -EIO) | ||
36 | goto out; | ||
37 | if (ret == -EBUSY) | ||
38 | continue; | ||
39 | |||
40 | __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT | | ||
41 | PSW_MASK_WAIT | PSW_DEFAULT_KEY); | ||
42 | local_irq_disable(); | ||
43 | barrier(); | ||
44 | |||
45 | response = sccb->response_code; | ||
46 | |||
47 | if (response == 0x10) | ||
48 | break; | ||
49 | |||
50 | if (response != 0x1f0 || command == SCLP_CMDW_READ_SCP_INFO) | ||
51 | break; | ||
52 | |||
53 | command = SCLP_CMDW_READ_SCP_INFO; | ||
54 | } | ||
55 | out: | ||
56 | __ctl_clear_bit(0, 9); /* disable service signal subclass mask */ | ||
57 | } | ||
diff --git a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c index 0c92d3909cca..2486783ea58e 100644 --- a/drivers/s390/char/sclp_rw.c +++ b/drivers/s390/char/sclp_rw.c | |||
@@ -460,7 +460,7 @@ sclp_emit_buffer(struct sclp_buffer *buffer, | |||
460 | sccb->msg_buf.header.type = EvTyp_PMsgCmd; | 460 | sccb->msg_buf.header.type = EvTyp_PMsgCmd; |
461 | else | 461 | else |
462 | return -ENOSYS; | 462 | return -ENOSYS; |
463 | buffer->request.command = SCLP_CMDW_WRITEDATA; | 463 | buffer->request.command = SCLP_CMDW_WRITE_EVENT_DATA; |
464 | buffer->request.status = SCLP_REQ_FILLED; | 464 | buffer->request.status = SCLP_REQ_FILLED; |
465 | buffer->request.callback = sclp_writedata_callback; | 465 | buffer->request.callback = sclp_writedata_callback; |
466 | buffer->request.callback_data = buffer; | 466 | buffer->request.callback_data = buffer; |
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index d8135cd4d7ab..544f137d70d7 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
@@ -207,7 +207,7 @@ __sclp_vt220_emit(struct sclp_vt220_request *request) | |||
207 | request->sclp_req.status = SCLP_REQ_FAILED; | 207 | request->sclp_req.status = SCLP_REQ_FAILED; |
208 | return -EIO; | 208 | return -EIO; |
209 | } | 209 | } |
210 | request->sclp_req.command = SCLP_CMDW_WRITEDATA; | 210 | request->sclp_req.command = SCLP_CMDW_WRITE_EVENT_DATA; |
211 | request->sclp_req.status = SCLP_REQ_FILLED; | 211 | request->sclp_req.status = SCLP_REQ_FILLED; |
212 | request->sclp_req.callback = sclp_vt220_callback; | 212 | request->sclp_req.callback = sclp_vt220_callback; |
213 | request->sclp_req.callback_data = (void *) request; | 213 | request->sclp_req.callback_data = (void *) request; |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index ad2b37929848..23e71a76cdab 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -895,11 +895,11 @@ static int stsch_reset(struct subchannel_id schid, volatile struct schib *addr) | |||
895 | int rc; | 895 | int rc; |
896 | 896 | ||
897 | pgm_check_occured = 0; | 897 | pgm_check_occured = 0; |
898 | s390_reset_pgm_handler = cio_reset_pgm_check_handler; | 898 | s390_base_pgm_handler_fn = cio_reset_pgm_check_handler; |
899 | rc = stsch(schid, addr); | 899 | rc = stsch(schid, addr); |
900 | s390_reset_pgm_handler = NULL; | 900 | s390_base_pgm_handler_fn = NULL; |
901 | 901 | ||
902 | /* The program check handler could have changed pgm_check_occured */ | 902 | /* The program check handler could have changed pgm_check_occured. */ |
903 | barrier(); | 903 | barrier(); |
904 | 904 | ||
905 | if (pgm_check_occured) | 905 | if (pgm_check_occured) |
@@ -957,7 +957,7 @@ static void css_reset(void) | |||
957 | /* Reset subchannels. */ | 957 | /* Reset subchannels. */ |
958 | for_each_subchannel(__shutdown_subchannel_easy, NULL); | 958 | for_each_subchannel(__shutdown_subchannel_easy, NULL); |
959 | /* Reset channel paths. */ | 959 | /* Reset channel paths. */ |
960 | s390_reset_mcck_handler = s390_reset_chpids_mcck_handler; | 960 | s390_base_mcck_handler_fn = s390_reset_chpids_mcck_handler; |
961 | /* Enable channel report machine checks. */ | 961 | /* Enable channel report machine checks. */ |
962 | __ctl_set_bit(14, 28); | 962 | __ctl_set_bit(14, 28); |
963 | /* Temporarily reenable machine checks. */ | 963 | /* Temporarily reenable machine checks. */ |
@@ -982,7 +982,7 @@ static void css_reset(void) | |||
982 | local_mcck_disable(); | 982 | local_mcck_disable(); |
983 | /* Disable channel report machine checks. */ | 983 | /* Disable channel report machine checks. */ |
984 | __ctl_clear_bit(14, 28); | 984 | __ctl_clear_bit(14, 28); |
985 | s390_reset_mcck_handler = NULL; | 985 | s390_base_mcck_handler_fn = NULL; |
986 | } | 986 | } |
987 | 987 | ||
988 | static struct reset_call css_reset_call = { | 988 | static struct reset_call css_reset_call = { |
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index cf71c5449240..4c1b73940351 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h | |||
@@ -331,6 +331,18 @@ static inline void disabled_wait(unsigned long code) | |||
331 | } | 331 | } |
332 | 332 | ||
333 | /* | 333 | /* |
334 | * Basic Machine Check/Program Check Handler. | ||
335 | */ | ||
336 | |||
337 | extern void s390_base_mcck_handler(void); | ||
338 | extern void s390_base_pgm_handler(void); | ||
339 | extern void s390_base_ext_handler(void); | ||
340 | |||
341 | extern void (*s390_base_mcck_handler_fn)(void); | ||
342 | extern void (*s390_base_pgm_handler_fn)(void); | ||
343 | extern void (*s390_base_ext_handler_fn)(void); | ||
344 | |||
345 | /* | ||
334 | * CPU idle notifier chain. | 346 | * CPU idle notifier chain. |
335 | */ | 347 | */ |
336 | #define CPU_IDLE 0 | 348 | #define CPU_IDLE 0 |
diff --git a/include/asm-s390/reset.h b/include/asm-s390/reset.h index 532e65a2aafc..f584f4a52581 100644 --- a/include/asm-s390/reset.h +++ b/include/asm-s390/reset.h | |||
@@ -18,7 +18,4 @@ struct reset_call { | |||
18 | extern void register_reset_call(struct reset_call *reset); | 18 | extern void register_reset_call(struct reset_call *reset); |
19 | extern void unregister_reset_call(struct reset_call *reset); | 19 | extern void unregister_reset_call(struct reset_call *reset); |
20 | extern void s390_reset_system(void); | 20 | extern void s390_reset_system(void); |
21 | extern void (*s390_reset_mcck_handler)(void); | ||
22 | extern void (*s390_reset_pgm_handler)(void); | ||
23 | |||
24 | #endif /* _ASM_S390_RESET_H */ | 21 | #endif /* _ASM_S390_RESET_H */ |
diff --git a/include/asm-s390/sclp.h b/include/asm-s390/sclp.h new file mode 100644 index 000000000000..468b97018405 --- /dev/null +++ b/include/asm-s390/sclp.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * include/asm-s390/sclp.h | ||
3 | * | ||
4 | * Copyright IBM Corp. 2007 | ||
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390_SCLP_H | ||
9 | #define _ASM_S390_SCLP_H | ||
10 | |||
11 | #include <linux/types.h> | ||
12 | |||
13 | struct sccb_header { | ||
14 | u16 length; | ||
15 | u8 function_code; | ||
16 | u8 control_mask[3]; | ||
17 | u16 response_code; | ||
18 | } __attribute__((packed)); | ||
19 | |||
20 | #define LOADPARM_LEN 8 | ||
21 | |||
22 | struct sclp_readinfo_sccb { | ||
23 | struct sccb_header header; /* 0-7 */ | ||
24 | u16 rnmax; /* 8-9 */ | ||
25 | u8 rnsize; /* 10 */ | ||
26 | u8 _reserved0[24 - 11]; /* 11-23 */ | ||
27 | u8 loadparm[LOADPARM_LEN]; /* 24-31 */ | ||
28 | u8 _reserved1[91 - 32]; /* 32-90 */ | ||
29 | u8 flags; /* 91 */ | ||
30 | u8 _reserved2[100 - 92]; /* 92-99 */ | ||
31 | u32 rnsize2; /* 100-103 */ | ||
32 | u64 rnmax2; /* 104-111 */ | ||
33 | u8 _reserved3[4096 - 112]; /* 112-4095 */ | ||
34 | } __attribute__((packed, aligned(4096))); | ||
35 | |||
36 | extern struct sclp_readinfo_sccb s390_readinfo_sccb; | ||
37 | extern void sclp_readinfo_early(void); | ||
38 | |||
39 | #endif /* _ASM_S390_SCLP_H */ | ||