diff options
Diffstat (limited to 'arch/s390/kernel')
-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 |
8 files changed, 467 insertions, 570 deletions
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; |