diff options
-rw-r--r-- | arch/s390/kernel/head.S | 59 | ||||
-rw-r--r-- | arch/s390/kernel/head31.S | 43 | ||||
-rw-r--r-- | arch/s390/kernel/head64.S | 39 | ||||
-rw-r--r-- | arch/s390/kernel/ipl.c | 4 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 38 | ||||
-rw-r--r-- | include/asm-s390/lowcore.h | 1 | ||||
-rw-r--r-- | include/asm-s390/setup.h | 8 |
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 | ||
516 | 0: lhi %r1,-1 # copy direction is downwards | ||
517 | ar %r2,%r0 | ||
518 | ar %r3,%r0 | ||
519 | ar %r2,%r1 | ||
520 | ar %r3,%r1 | ||
521 | 1: 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 | ||
535 | ipl_parameter_flags: | ||
536 | .long 0 | ||
537 | .globl ipl_devno | ||
538 | ipl_devno: | ||
539 | .word 0 | ||
540 | 2: | ||
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 | ||
38 | startup_continue: | 38 | startup_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 | ||
293 | ipl_schib: | ||
294 | .rept 13 | ||
295 | .long 0 | ||
296 | .endr | ||
297 | |||
298 | .globl ipl_flags | ||
299 | ipl_flags: | ||
300 | .long 0 | ||
301 | .globl ipl_devno | ||
302 | ipl_devno: | ||
303 | .word 0 | ||
304 | |||
277 | .org 0x12000 | 305 | .org 0x12000 |
278 | .globl s390_readinfo_sccb | 306 | .globl s390_readinfo_sccb |
279 | s390_readinfo_sccb: | 307 | s390_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 | ||
283 | ipl_schib: | ||
284 | .rept 13 | ||
285 | .long 0 | ||
286 | .endr | ||
287 | |||
288 | .globl ipl_flags | ||
289 | ipl_flags: | ||
290 | .long 0 | ||
291 | .globl ipl_devno | ||
292 | ipl_devno: | ||
293 | .word 0 | ||
294 | |||
272 | .org 0x12000 | 295 | .org 0x12000 |
273 | .globl s390_readinfo_sccb | 296 | .globl s390_readinfo_sccb |
274 | s390_readinfo_sccb: | 297 | s390_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 | |||
912 | extern 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 | */ | ||
922 | void 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 | */ |
128 | extern u32 ipl_parameter_flags; | 128 | extern u32 ipl_flags; |
129 | extern u16 ipl_devno; | 129 | extern u16 ipl_devno; |
130 | 130 | ||
131 | void do_reipl(void); | 131 | void do_reipl(void); |
132 | 132 | ||
133 | #define IPL_DEVNO_VALID (ipl_parameter_flags & 1) | 133 | enum { |
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) |