aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/kernel/head.S59
-rw-r--r--arch/s390/kernel/head31.S43
-rw-r--r--arch/s390/kernel/head64.S39
-rw-r--r--arch/s390/kernel/ipl.c4
-rw-r--r--drivers/s390/cio/cio.c38
-rw-r--r--include/asm-s390/lowcore.h1
-rw-r--r--include/asm-s390/setup.h8
7 files changed, 99 insertions, 93 deletions
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index a6e9bdb53591..0f1db268a8a9 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -481,65 +481,6 @@ start:
481 .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 481 .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
482 .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff 482 .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
483 483
484.macro GET_IPL_DEVICE
485.Lget_ipl_device:
486 l %r1,0xb8 # get sid
487 sll %r1,15 # test if subchannel is enabled
488 srl %r1,31
489 ltr %r1,%r1
490 bz 2f-.LPG1(%r13) # subchannel disabled
491 l %r1,0xb8
492 la %r5,.Lipl_schib-.LPG1(%r13)
493 stsch 0(%r5) # get schib of subchannel
494 bnz 2f-.LPG1(%r13) # schib not available
495 tm 5(%r5),0x01 # devno valid?
496 bno 2f-.LPG1(%r13)
497 la %r6,ipl_parameter_flags-.LPG1(%r13)
498 oi 3(%r6),0x01 # set flag
499 la %r2,ipl_devno-.LPG1(%r13)
500 mvc 0(2,%r2),6(%r5) # store devno
501 tm 4(%r5),0x80 # qdio capable device?
502 bno 2f-.LPG1(%r13)
503 oi 3(%r6),0x02 # set flag
504
505 # copy ipl parameters
506
507 lhi %r0,4096
508 l %r2,20(%r0) # get address of parameter list
509 lhi %r3,IPL_PARMBLOCK_ORIGIN
510 st %r3,20(%r0)
511 lhi %r4,1
512 cr %r2,%r3 # start parameters < destination ?
513 jl 0f
514 lhi %r1,1 # copy direction is upwards
515 j 1f
5160: lhi %r1,-1 # copy direction is downwards
517 ar %r2,%r0
518 ar %r3,%r0
519 ar %r2,%r1
520 ar %r3,%r1
5211: mvc 0(1,%r3),0(%r2) # finally copy ipl parameters
522 ar %r3,%r1
523 ar %r2,%r1
524 sr %r0,%r4
525 jne 1b
526 b 2f-.LPG1(%r13)
527
528 .align 4
529.Lipl_schib:
530 .rept 13
531 .long 0
532 .endr
533
534 .globl ipl_parameter_flags
535ipl_parameter_flags:
536 .long 0
537 .globl ipl_devno
538ipl_devno:
539 .word 0
5402:
541.endm
542
543#ifdef CONFIG_64BIT 484#ifdef CONFIG_64BIT
544#include "head64.S" 485#include "head64.S"
545#else 486#else
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
index d8bb68a72527..1fa9fa1ca740 100644
--- a/arch/s390/kernel/head31.S
+++ b/arch/s390/kernel/head31.S
@@ -37,13 +37,23 @@ startup:basr %r13,0 # get base
37 37
38startup_continue: 38startup_continue:
39 basr %r13,0 # get base 39 basr %r13,0 # get base
40.LPG1: GET_IPL_DEVICE 40.LPG1: mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
41 mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
42 lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers 41 lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
43 l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area 42 l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
44 # move IPL device to lowcore 43 # move IPL device to lowcore
45 mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12) 44 mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
45#
46# Setup stack
47#
48 l %r15,.Linittu-.LPG1(%r13)
49 mvc __LC_CURRENT(4),__TI_task(%r15)
50 ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
51 st %r15,__LC_KERNEL_STACK # set end of kernel stack
52 ahi %r15,-96
53 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
46 54
55 l %r14,.Lipl_save_parameters-.LPG1(%r13)
56 basr %r14,%r14
47# 57#
48# clear bss memory 58# clear bss memory
49# 59#
@@ -115,6 +125,10 @@ startup_continue:
115 b .Lfchunk-.LPG1(%r13) 125 b .Lfchunk-.LPG1(%r13)
116 126
117 .align 4 127 .align 4
128.Lipl_save_parameters:
129 .long ipl_save_parameters
130.Linittu:
131 .long init_thread_union
118.Lpmask: 132.Lpmask:
119 .byte 0 133 .byte 0
120.align 8 134.align 8
@@ -274,6 +288,20 @@ startup_continue:
274.Lbss_end: .long _end 288.Lbss_end: .long _end
275.Lparmaddr: .long PARMAREA 289.Lparmaddr: .long PARMAREA
276.Lsccbaddr: .long .Lsccb 290.Lsccbaddr: .long .Lsccb
291
292 .globl ipl_schib
293ipl_schib:
294 .rept 13
295 .long 0
296 .endr
297
298 .globl ipl_flags
299ipl_flags:
300 .long 0
301 .globl ipl_devno
302ipl_devno:
303 .word 0
304
277 .org 0x12000 305 .org 0x12000
278.globl s390_readinfo_sccb 306.globl s390_readinfo_sccb
279s390_readinfo_sccb: 307s390_readinfo_sccb:
@@ -305,16 +333,6 @@ s390_readinfo_sccb:
305 .globl _stext 333 .globl _stext
306_stext: basr %r13,0 # get base 334_stext: basr %r13,0 # get base
307.LPG3: 335.LPG3:
308#
309# Setup stack
310#
311 l %r15,.Linittu-.LPG3(%r13)
312 mvc __LC_CURRENT(4),__TI_task(%r15)
313 ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
314 st %r15,__LC_KERNEL_STACK # set end of kernel stack
315 ahi %r15,-96
316 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
317
318# check control registers 336# check control registers
319 stctl %c0,%c15,0(%r15) 337 stctl %c0,%c15,0(%r15)
320 oi 2(%r15),0x40 # enable sigp emergency signal 338 oi 2(%r15),0x40 # enable sigp emergency signal
@@ -333,6 +351,5 @@ _stext: basr %r13,0 # get base
333# 351#
334 .align 8 352 .align 8
335.Ldw: .long 0x000a0000,0x00000000 353.Ldw: .long 0x000a0000,0x00000000
336.Linittu:.long init_thread_union
337.Lstart:.long start_kernel 354.Lstart:.long start_kernel
338.Laregs:.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 355.Laregs:.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index c2005101fee1..1ebaa338aa7e 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -39,7 +39,6 @@ startup_continue:
39 basr %r13,0 # get base 39 basr %r13,0 # get base
40.LPG1: sll %r13,1 # remove high order bit 40.LPG1: sll %r13,1 # remove high order bit
41 srl %r13,1 41 srl %r13,1
42 GET_IPL_DEVICE
43 lhi %r1,1 # mode 1 = esame 42 lhi %r1,1 # mode 1 = esame
44 mvi __LC_AR_MODE_ID,1 # set esame flag 43 mvi __LC_AR_MODE_ID,1 # set esame flag
45 slr %r0,%r0 # set cpuid to zero 44 slr %r0,%r0 # set cpuid to zero
@@ -49,7 +48,18 @@ startup_continue:
49 lg %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area 48 lg %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area
50 # move IPL device to lowcore 49 # move IPL device to lowcore
51 mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) 50 mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
51#
52# Setup stack
53#
54 larl %r15,init_thread_union
55 lg %r14,__TI_task(%r15) # cache current in lowcore
56 stg %r14,__LC_CURRENT
57 aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
58 stg %r15,__LC_KERNEL_STACK # set end of kernel stack
59 aghi %r15,-160
60 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
52 61
62 brasl %r14,ipl_save_parameters
53# 63#
54# clear bss memory 64# clear bss memory
55# 65#
@@ -269,6 +279,19 @@ startup_continue:
269.Lparmaddr: 279.Lparmaddr:
270 .quad PARMAREA 280 .quad PARMAREA
271 281
282 .globl ipl_schib
283ipl_schib:
284 .rept 13
285 .long 0
286 .endr
287
288 .globl ipl_flags
289ipl_flags:
290 .long 0
291 .globl ipl_devno
292ipl_devno:
293 .word 0
294
272 .org 0x12000 295 .org 0x12000
273.globl s390_readinfo_sccb 296.globl s390_readinfo_sccb
274s390_readinfo_sccb: 297s390_readinfo_sccb:
@@ -300,24 +323,12 @@ s390_readinfo_sccb:
300 .globl _stext 323 .globl _stext
301_stext: basr %r13,0 # get base 324_stext: basr %r13,0 # get base
302.LPG3: 325.LPG3:
303#
304# Setup stack
305#
306 larl %r15,init_thread_union
307 lg %r14,__TI_task(%r15) # cache current in lowcore
308 stg %r14,__LC_CURRENT
309 aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
310 stg %r15,__LC_KERNEL_STACK # set end of kernel stack
311 aghi %r15,-160
312 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
313
314# check control registers 326# check control registers
315 stctg %c0,%c15,0(%r15) 327 stctg %c0,%c15,0(%r15)
316 oi 6(%r15),0x40 # enable sigp emergency signal 328 oi 6(%r15),0x40 # enable sigp emergency signal
317 oi 4(%r15),0x10 # switch on low address proctection 329 oi 4(%r15),0x10 # switch on low address proctection
318 lctlg %c0,%c15,0(%r15) 330 lctlg %c0,%c15,0(%r15)
319 331
320#
321 lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess 332 lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
322 brasl %r14,start_kernel # go to C code 333 brasl %r14,start_kernel # go to C code
323# 334#
@@ -325,7 +336,7 @@ _stext: basr %r13,0 # get base
325# 336#
326 basr %r13,0 337 basr %r13,0
327 lpswe .Ldw-.(%r13) # load disabled wait psw 338 lpswe .Ldw-.(%r13) # load disabled wait psw
328# 339
329 .align 8 340 .align 8
330.Ldw: .quad 0x0002000180000000,0x0000000000000000 341.Ldw: .quad 0x0002000180000000,0x0000000000000000
331.Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 342.Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 105ee15a2b31..6555cc48e28f 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -189,9 +189,9 @@ static enum ipl_type ipl_get_type(void)
189{ 189{
190 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; 190 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
191 191
192 if (!IPL_DEVNO_VALID) 192 if (!(ipl_flags & IPL_DEVNO_VALID))
193 return IPL_TYPE_UNKNOWN; 193 return IPL_TYPE_UNKNOWN;
194 if (!IPL_PARMBLOCK_VALID) 194 if (!(ipl_flags & IPL_PARMBLOCK_VALID))
195 return IPL_TYPE_CCW; 195 return IPL_TYPE_CCW;
196 if (ipl->hdr.version > IPL_MAX_SUPPORTED_VERSION) 196 if (ipl->hdr.version > IPL_MAX_SUPPORTED_VERSION)
197 return IPL_TYPE_UNKNOWN; 197 return IPL_TYPE_UNKNOWN;
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 050963f15802..61eb7caa1567 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -16,11 +16,10 @@
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/kernel_stat.h> 17#include <linux/kernel_stat.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19
20#include <asm/cio.h> 19#include <asm/cio.h>
21#include <asm/delay.h> 20#include <asm/delay.h>
22#include <asm/irq.h> 21#include <asm/irq.h>
23 22#include <asm/setup.h>
24#include "airq.h" 23#include "airq.h"
25#include "cio.h" 24#include "cio.h"
26#include "css.h" 25#include "css.h"
@@ -909,3 +908,38 @@ void reipl_ccw_dev(struct ccw_dev_id *devid)
909 cio_reset_channel_paths(); 908 cio_reset_channel_paths();
910 do_reipl_asm(*((__u32*)&schid)); 909 do_reipl_asm(*((__u32*)&schid));
911} 910}
911
912extern struct schib ipl_schib;
913
914/*
915 * ipl_save_parameters gets called very early. It is not allowed to access
916 * anything in the bss section at all. The bss section is not cleared yet,
917 * but may contain some ipl parameters written by the firmware.
918 * These parameters (if present) are copied to 0x2000.
919 * To avoid corruption of the ipl parameters, all variables used by this
920 * function must reside on the stack or in the data section.
921 */
922void ipl_save_parameters(void)
923{
924 struct subchannel_id schid;
925 unsigned int *ipl_ptr;
926 void *src, *dst;
927
928 schid = *(struct subchannel_id *)__LC_SUBCHANNEL_ID;
929 if (!schid.one)
930 return;
931 if (stsch(schid, &ipl_schib))
932 return;
933 if (!ipl_schib.pmcw.dnv)
934 return;
935 ipl_devno = ipl_schib.pmcw.dev;
936 ipl_flags |= IPL_DEVNO_VALID;
937 if (!ipl_schib.pmcw.qf)
938 return;
939 ipl_flags |= IPL_PARMBLOCK_VALID;
940 ipl_ptr = (unsigned int *)__LC_IPL_PARMBLOCK_PTR;
941 src = (void *)(unsigned long)*ipl_ptr;
942 dst = (void *)IPL_PARMBLOCK_ORIGIN;
943 memmove(dst, src, PAGE_SIZE);
944 *ipl_ptr = IPL_PARMBLOCK_ORIGIN;
945}
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h
index 2e3d4cca5e21..18695d10dedf 100644
--- a/include/asm-s390/lowcore.h
+++ b/include/asm-s390/lowcore.h
@@ -35,6 +35,7 @@
35#define __LC_IO_NEW_PSW 0x01f0 35#define __LC_IO_NEW_PSW 0x01f0
36#endif /* !__s390x__ */ 36#endif /* !__s390x__ */
37 37
38#define __LC_IPL_PARMBLOCK_PTR 0x014
38#define __LC_EXT_PARAMS 0x080 39#define __LC_EXT_PARAMS 0x080
39#define __LC_CPU_ADDRESS 0x084 40#define __LC_CPU_ADDRESS 0x084
40#define __LC_EXT_INT_CODE 0x086 41#define __LC_EXT_INT_CODE 0x086
diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h
index 4a1126d8439a..00c03e46689b 100644
--- a/include/asm-s390/setup.h
+++ b/include/asm-s390/setup.h
@@ -125,13 +125,15 @@ struct ipl_parameter_block {
125/* 125/*
126 * IPL validity flags and parameters as detected in head.S 126 * IPL validity flags and parameters as detected in head.S
127 */ 127 */
128extern u32 ipl_parameter_flags; 128extern u32 ipl_flags;
129extern u16 ipl_devno; 129extern u16 ipl_devno;
130 130
131void do_reipl(void); 131void do_reipl(void);
132 132
133#define IPL_DEVNO_VALID (ipl_parameter_flags & 1) 133enum {
134#define IPL_PARMBLOCK_VALID (ipl_parameter_flags & 2) 134 IPL_DEVNO_VALID = 1,
135 IPL_PARMBLOCK_VALID = 2,
136};
135 137
136#define IPL_PARMBLOCK_START ((struct ipl_parameter_block *) \ 138#define IPL_PARMBLOCK_START ((struct ipl_parameter_block *) \
137 IPL_PARMBLOCK_ORIGIN) 139 IPL_PARMBLOCK_ORIGIN)