diff options
Diffstat (limited to 'arch/s390/kernel')
| -rw-r--r-- | arch/s390/kernel/Makefile | 4 | ||||
| -rw-r--r-- | arch/s390/kernel/debug.c | 12 | ||||
| -rw-r--r-- | arch/s390/kernel/entry.S | 4 | ||||
| -rw-r--r-- | arch/s390/kernel/entry64.S | 4 | ||||
| -rw-r--r-- | arch/s390/kernel/head.S | 383 | ||||
| -rw-r--r-- | arch/s390/kernel/head31.S | 336 | ||||
| -rw-r--r-- | arch/s390/kernel/head64.S | 543 | ||||
| -rw-r--r-- | arch/s390/kernel/process.c | 24 | ||||
| -rw-r--r-- | arch/s390/kernel/smp.c | 1 | ||||
| -rw-r--r-- | arch/s390/kernel/time.c | 8 | ||||
| -rw-r--r-- | arch/s390/kernel/traps.c | 29 | 
11 files changed, 418 insertions, 930 deletions
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 8584dd823218..7434c32bc631 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile  | |||
| @@ -8,9 +8,7 @@ obj-y := bitmap.o traps.o time.o process.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 profile.o irq.o reipl_diag.o | 9 | semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o | 
| 10 | 10 | ||
| 11 | extra-$(CONFIG_ARCH_S390_31) += head.o | 11 | extra-y += head.o init_task.o vmlinux.lds | 
| 12 | extra-$(CONFIG_ARCH_S390X) += head64.o | ||
| 13 | extra-y += init_task.o vmlinux.lds | ||
| 14 | 12 | ||
| 15 | obj-$(CONFIG_MODULES) += s390_ksyms.o module.o | 13 | obj-$(CONFIG_MODULES) += s390_ksyms.o module.o | 
| 16 | obj-$(CONFIG_SMP) += smp.o | 14 | obj-$(CONFIG_SMP) += smp.o | 
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index bc59282da762..896d39d0e4ce 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c  | |||
| @@ -486,7 +486,7 @@ out: | |||
| 486 | * - goto next entry in p_info | 486 | * - goto next entry in p_info | 
| 487 | */ | 487 | */ | 
| 488 | 488 | ||
| 489 | extern inline int | 489 | static inline int | 
| 490 | debug_next_entry(file_private_info_t *p_info) | 490 | debug_next_entry(file_private_info_t *p_info) | 
| 491 | { | 491 | { | 
| 492 | debug_info_t *id; | 492 | debug_info_t *id; | 
| @@ -800,7 +800,7 @@ debug_set_level(debug_info_t* id, int new_level) | |||
| 800 | * - set active entry to next in the ring buffer | 800 | * - set active entry to next in the ring buffer | 
| 801 | */ | 801 | */ | 
| 802 | 802 | ||
| 803 | extern inline void | 803 | static inline void | 
| 804 | proceed_active_entry(debug_info_t * id) | 804 | proceed_active_entry(debug_info_t * id) | 
| 805 | { | 805 | { | 
| 806 | if ((id->active_entries[id->active_area] += id->entry_size) | 806 | if ((id->active_entries[id->active_area] += id->entry_size) | 
| @@ -817,7 +817,7 @@ proceed_active_entry(debug_info_t * id) | |||
| 817 | * - set active area to next in the ring buffer | 817 | * - set active area to next in the ring buffer | 
| 818 | */ | 818 | */ | 
| 819 | 819 | ||
| 820 | extern inline void | 820 | static inline void | 
| 821 | proceed_active_area(debug_info_t * id) | 821 | proceed_active_area(debug_info_t * id) | 
| 822 | { | 822 | { | 
| 823 | id->active_area++; | 823 | id->active_area++; | 
| @@ -828,7 +828,7 @@ proceed_active_area(debug_info_t * id) | |||
| 828 | * get_active_entry: | 828 | * get_active_entry: | 
| 829 | */ | 829 | */ | 
| 830 | 830 | ||
| 831 | extern inline debug_entry_t* | 831 | static inline debug_entry_t* | 
| 832 | get_active_entry(debug_info_t * id) | 832 | get_active_entry(debug_info_t * id) | 
| 833 | { | 833 | { | 
| 834 | return (debug_entry_t *) (((char *) id->areas[id->active_area] | 834 | return (debug_entry_t *) (((char *) id->areas[id->active_area] | 
| @@ -841,7 +841,7 @@ get_active_entry(debug_info_t * id) | |||
| 841 | * - set timestamp, caller address, cpu number etc. | 841 | * - set timestamp, caller address, cpu number etc. | 
| 842 | */ | 842 | */ | 
| 843 | 843 | ||
| 844 | extern inline void | 844 | static inline void | 
| 845 | debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level, | 845 | debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level, | 
| 846 | int exception) | 846 | int exception) | 
| 847 | { | 847 | { | 
| @@ -971,7 +971,7 @@ debug_entry_t | |||
| 971 | * counts arguments in format string for sprintf view | 971 | * counts arguments in format string for sprintf view | 
| 972 | */ | 972 | */ | 
| 973 | 973 | ||
| 974 | extern inline int | 974 | static inline int | 
| 975 | debug_count_numargs(char *string) | 975 | debug_count_numargs(char *string) | 
| 976 | { | 976 | { | 
| 977 | int numargs=0; | 977 | int numargs=0; | 
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 9b30f4cf32c4..27b07730b7b8 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S  | |||
| @@ -288,7 +288,7 @@ sysc_sigpending: | |||
| 288 | bo BASED(sysc_restart) | 288 | bo BASED(sysc_restart) | 
| 289 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP | 289 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP | 
| 290 | bo BASED(sysc_singlestep) | 290 | bo BASED(sysc_singlestep) | 
| 291 | b BASED(sysc_leave) # out of here, do NOT recheck | 291 | b BASED(sysc_work_loop) | 
| 292 | 292 | ||
| 293 | # | 293 | # | 
| 294 | # _TIF_RESTART_SVC is set, set up registers and restart svc | 294 | # _TIF_RESTART_SVC is set, set up registers and restart svc | 
| @@ -645,7 +645,7 @@ io_sigpending: | |||
| 645 | l %r1,BASED(.Ldo_signal) | 645 | l %r1,BASED(.Ldo_signal) | 
| 646 | basr %r14,%r1 # call do_signal | 646 | basr %r14,%r1 # call do_signal | 
| 647 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 647 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 
| 648 | b BASED(io_leave) # out of here, do NOT recheck | 648 | b BASED(io_work_loop) | 
| 649 | 649 | ||
| 650 | /* | 650 | /* | 
| 651 | * External interrupt handler routine | 651 | * External interrupt handler routine | 
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 7b9b4a2ba1d7..4eb71ffcf484 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S  | |||
| @@ -283,7 +283,7 @@ sysc_sigpending: | |||
| 283 | jo sysc_restart | 283 | jo sysc_restart | 
| 284 | tm __TI_flags+7(%r9),_TIF_SINGLE_STEP | 284 | tm __TI_flags+7(%r9),_TIF_SINGLE_STEP | 
| 285 | jo sysc_singlestep | 285 | jo sysc_singlestep | 
| 286 | j sysc_leave # out of here, do NOT recheck | 286 | j sysc_work_loop | 
| 287 | 287 | ||
| 288 | # | 288 | # | 
| 289 | # _TIF_RESTART_SVC is set, set up registers and restart svc | 289 | # _TIF_RESTART_SVC is set, set up registers and restart svc | 
| @@ -684,7 +684,7 @@ io_sigpending: | |||
| 684 | slgr %r3,%r3 # clear *oldset | 684 | slgr %r3,%r3 # clear *oldset | 
| 685 | brasl %r14,do_signal # call do_signal | 685 | brasl %r14,do_signal # call do_signal | 
| 686 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 686 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 
| 687 | j sysc_leave # out of here, do NOT recheck | 687 | j io_work_loop | 
| 688 | 688 | ||
| 689 | /* | 689 | /* | 
| 690 | * External interrupt handler routine | 690 | * External interrupt handler routine | 
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index 039354d72348..d31a97c89f68 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S  | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | /* | 1 | /* | 
| 2 | * arch/s390/kernel/head.S | 2 | * arch/s390/kernel/head.S | 
| 3 | * | 3 | * | 
| 4 | * S390 version | 4 | * (C) Copyright IBM Corp. 1999, 2005 | 
| 5 | * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation | 5 | * | 
| 6 | * Author(s): Hartmut Penner (hp@de.ibm.com), | 6 | * Author(s): Hartmut Penner <hp@de.ibm.com> | 
| 7 | * Martin Schwidefsky (schwidefsky@de.ibm.com), | 7 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 
| 8 | * Rob van der Heij (rvdhei@iae.nl) | 8 | * Rob van der Heij <rvdhei@iae.nl> | 
| 9 | * Heiko Carstens <heiko.carstens@de.ibm.com> | ||
| 9 | * | 10 | * | 
| 10 | * There are 5 different IPL methods | 11 | * There are 5 different IPL methods | 
| 11 | * 1) load the image directly into ram at address 0 and do an PSW restart | 12 | * 1) load the image directly into ram at address 0 and do an PSW restart | 
| @@ -19,12 +20,7 @@ | |||
| 19 | * 5) direct call of start by the SALIPL loader | 20 | * 5) direct call of start by the SALIPL loader | 
| 20 | * We use the cpuid to distinguish between VM and native ipl | 21 | * We use the cpuid to distinguish between VM and native ipl | 
| 21 | * params for kernel are pushed to 0x10400 (see setup.h) | 22 | * params for kernel are pushed to 0x10400 (see setup.h) | 
| 22 | 23 | * | |
| 23 | Changes: | ||
| 24 | Okt 25 2000 <rvdheij@iae.nl> | ||
| 25 | added code to skip HDR and EOF to allow SL tape IPL (5 retries) | ||
| 26 | changed first CCW from rewind to backspace block | ||
| 27 | |||
| 28 | */ | 24 | */ | 
| 29 | 25 | ||
| 30 | #include <linux/config.h> | 26 | #include <linux/config.h> | 
| @@ -34,6 +30,12 @@ | |||
| 34 | #include <asm/thread_info.h> | 30 | #include <asm/thread_info.h> | 
| 35 | #include <asm/page.h> | 31 | #include <asm/page.h> | 
| 36 | 32 | ||
| 33 | #ifdef CONFIG_ARCH_S390X | ||
| 34 | #define ARCH_OFFSET 4 | ||
| 35 | #else | ||
| 36 | #define ARCH_OFFSET 0 | ||
| 37 | #endif | ||
| 38 | |||
| 37 | #ifndef CONFIG_IPL | 39 | #ifndef CONFIG_IPL | 
| 38 | .org 0 | 40 | .org 0 | 
| 39 | .long 0x00080000,0x80000000+startup # Just a restart PSW | 41 | .long 0x00080000,0x80000000+startup # Just a restart PSW | 
| @@ -201,7 +203,7 @@ | |||
| 201 | ssch 0(%r3) # load chunk of 1600 bytes | 203 | ssch 0(%r3) # load chunk of 1600 bytes | 
| 202 | bnz .Llderr | 204 | bnz .Llderr | 
| 203 | .Lwait4irq: | 205 | .Lwait4irq: | 
| 204 | mvc __LC_IO_NEW_PSW(8),.Lnewpsw # set up IO interrupt psw | 206 | mvc 0x78(8),.Lnewpsw # set up IO interrupt psw | 
| 205 | lpsw .Lwaitpsw | 207 | lpsw .Lwaitpsw | 
| 206 | .Lioint: | 208 | .Lioint: | 
| 207 | c %r1,0xb8 # compare subchannel number | 209 | c %r1,0xb8 # compare subchannel number | 
| @@ -265,13 +267,13 @@ iplstart: | |||
| 265 | la %r2,IPL_BS # load start address | 267 | la %r2,IPL_BS # load start address | 
| 266 | bas %r14,.Lloader # load rest of ipl image | 268 | bas %r14,.Lloader # load rest of ipl image | 
| 267 | l %r12,.Lparm # pointer to parameter area | 269 | l %r12,.Lparm # pointer to parameter area | 
| 268 | st %r1,IPL_DEVICE-PARMAREA(%r12) # store ipl device number | 270 | st %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number | 
| 269 | 271 | ||
| 270 | # | 272 | # | 
| 271 | # load parameter file from ipl device | 273 | # load parameter file from ipl device | 
| 272 | # | 274 | # | 
| 273 | .Lagain1: | 275 | .Lagain1: | 
| 274 | l %r2,INITRD_START-PARMAREA(%r12) # use ramdisk location as temp | 276 | l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # ramdisk loc. is temp | 
| 275 | bas %r14,.Lloader # load parameter file | 277 | bas %r14,.Lloader # load parameter file | 
| 276 | ltr %r2,%r2 # got anything ? | 278 | ltr %r2,%r2 # got anything ? | 
| 277 | bz .Lnopf | 279 | bz .Lnopf | 
| @@ -279,7 +281,7 @@ iplstart: | |||
| 279 | bnh .Lnotrunc | 281 | bnh .Lnotrunc | 
| 280 | la %r2,895 | 282 | la %r2,895 | 
| 281 | .Lnotrunc: | 283 | .Lnotrunc: | 
| 282 | l %r4,INITRD_START-PARMAREA(%r12) | 284 | l %r4,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) | 
| 283 | clc 0(3,%r4),.L_hdr # if it is HDRx | 285 | clc 0(3,%r4),.L_hdr # if it is HDRx | 
| 284 | bz .Lagain1 # skip dataset header | 286 | bz .Lagain1 # skip dataset header | 
| 285 | clc 0(3,%r4),.L_eof # if it is EOFx | 287 | clc 0(3,%r4),.L_eof # if it is EOFx | 
| @@ -322,14 +324,14 @@ iplstart: | |||
| 322 | # load ramdisk from ipl device | 324 | # load ramdisk from ipl device | 
| 323 | # | 325 | # | 
| 324 | .Lagain2: | 326 | .Lagain2: | 
| 325 | l %r2,INITRD_START-PARMAREA(%r12) # load adr. of ramdisk | 327 | l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # addr of ramdisk | 
| 326 | bas %r14,.Lloader # load ramdisk | 328 | bas %r14,.Lloader # load ramdisk | 
| 327 | st %r2,INITRD_SIZE-PARMAREA(%r12) # store size of ramdisk | 329 | st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk | 
| 328 | ltr %r2,%r2 | 330 | ltr %r2,%r2 | 
| 329 | bnz .Lrdcont | 331 | bnz .Lrdcont | 
| 330 | st %r2,INITRD_START-PARMAREA(%r12) # no ramdisk found, null it | 332 | st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found | 
| 331 | .Lrdcont: | 333 | .Lrdcont: | 
| 332 | l %r2,INITRD_START-PARMAREA(%r12) | 334 | l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) | 
| 333 | 335 | ||
| 334 | clc 0(3,%r2),.L_hdr # skip HDRx and EOFx | 336 | clc 0(3,%r2),.L_hdr # skip HDRx and EOFx | 
| 335 | bz .Lagain2 | 337 | bz .Lagain2 | 
| @@ -432,10 +434,10 @@ start: | |||
| 432 | la %r3,1(%r3) | 434 | la %r3,1(%r3) | 
| 433 | .done: | 435 | .done: | 
| 434 | l %r1,.memsize | 436 | l %r1,.memsize | 
| 435 | st %r3,0(%r1) | 437 | st %r3,ARCH_OFFSET(%r1) | 
| 436 | slr %r0,%r0 | 438 | slr %r0,%r0 | 
| 437 | st %r0,INITRD_SIZE-PARMAREA(%r11) | 439 | st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11) | 
| 438 | st %r0,INITRD_START-PARMAREA(%r11) | 440 | st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11) | 
| 439 | j startup # continue with startup | 441 | j startup # continue with startup | 
| 440 | .tbl: .long _ebcasc # translate table | 442 | .tbl: .long _ebcasc # translate table | 
| 441 | .cmd: .long COMMAND_LINE # address of command line buffer | 443 | .cmd: .long COMMAND_LINE # address of command line buffer | 
| @@ -478,304 +480,23 @@ start: | |||
| 478 | .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 | 480 | .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 | 
| 479 | .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff | 481 | .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff | 
| 480 | 482 | ||
| 481 | # | 483 | .macro GET_IPL_DEVICE | 
| 482 | # startup-code at 0x10000, running in real mode | ||
| 483 | # this is called either by the ipl loader or directly by PSW restart | ||
| 484 | # or linload or SALIPL | ||
| 485 | # | ||
| 486 | .org 0x10000 | ||
| 487 | startup:basr %r13,0 # get base | ||
| 488 | .LPG1: l %r1, .Lget_ipl_device_addr-.LPG1(%r13) | ||
| 489 | basr %r14, %r1 | ||
| 490 | lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers | ||
| 491 | la %r12,_pstart-.LPG1(%r13) # pointer to parameter area | ||
| 492 | # move IPL device to lowcore | ||
| 493 | mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12) | ||
| 494 | |||
| 495 | # | ||
| 496 | # clear bss memory | ||
| 497 | # | ||
| 498 | l %r2,.Lbss_bgn-.LPG1(%r13) # start of bss | ||
| 499 | l %r3,.Lbss_end-.LPG1(%r13) # end of bss | ||
| 500 | sr %r3,%r2 # length of bss | ||
| 501 | sr %r4,%r4 # | ||
| 502 | sr %r5,%r5 # set src,length and pad to zero | ||
| 503 | sr %r0,%r0 # | ||
| 504 | mvcle %r2,%r4,0 # clear mem | ||
| 505 | jo .-4 # branch back, if not finish | ||
| 506 | |||
| 507 | l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word | ||
| 508 | .Lservicecall: | ||
| 509 | stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts | ||
| 510 | |||
| 511 | stctl %r0, %r0,.Lcr-.LPG1(%r13) # get cr0 | ||
| 512 | la %r1,0x200 # set bit 22 | ||
| 513 | o %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1 | ||
| 514 | st %r1,.Lcr-.LPG1(%r13) | ||
| 515 | lctl %r0, %r0,.Lcr-.LPG1(%r13) # load modified cr0 | ||
| 516 | |||
| 517 | mvc __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw | ||
| 518 | la %r1, .Lsclph-.LPG1(%r13) | ||
| 519 | a %r1,__LC_EXT_NEW_PSW+4 # set handler | ||
| 520 | st %r1,__LC_EXT_NEW_PSW+4 | ||
| 521 | |||
| 522 | la %r4,_pstart-.LPG1(%r13) # %r4 is our index for sccb stuff | ||
| 523 | la %r1, .Lsccb-PARMAREA(%r4) # our sccb | ||
| 524 | .insn rre,0xb2200000,%r2,%r1 # service call | ||
| 525 | ipm %r1 | ||
| 526 | srl %r1,28 # get cc code | ||
| 527 | xr %r3, %r3 | ||
| 528 | chi %r1,3 | ||
| 529 | be .Lfchunk-.LPG1(%r13) # leave | ||
| 530 | chi %r1,2 | ||
| 531 | be .Lservicecall-.LPG1(%r13) | ||
| 532 | lpsw .Lwaitsclp-.LPG1(%r13) | ||
| 533 | .Lsclph: | ||
| 534 | lh %r1,.Lsccbr-PARMAREA(%r4) | ||
| 535 | chi %r1,0x10 # 0x0010 is the sucess code | ||
| 536 | je .Lprocsccb # let's process the sccb | ||
| 537 | chi %r1,0x1f0 | ||
| 538 | bne .Lfchunk-.LPG1(%r13) # unhandled error code | ||
| 539 | c %r2, .Lrcp-.LPG1(%r13) # Did we try Read SCP forced | ||
| 540 | bne .Lfchunk-.LPG1(%r13) # if no, give up | ||
| 541 | l %r2, .Lrcp2-.LPG1(%r13) # try with Read SCP | ||
| 542 | b .Lservicecall-.LPG1(%r13) | ||
| 543 | .Lprocsccb: | ||
| 544 | lhi %r1,0 | ||
| 545 | icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 | ||
| 546 | jnz .Lscnd | ||
| 547 | lhi %r1,0x800 # otherwise report 2GB | ||
| 548 | .Lscnd: | ||
| 549 | lhi %r3,0x800 # limit reported memory size to 2GB | ||
| 550 | cr %r1,%r3 | ||
| 551 | jl .Lno2gb | ||
| 552 | lr %r1,%r3 | ||
| 553 | .Lno2gb: | ||
| 554 | xr %r3,%r3 # same logic | ||
| 555 | ic %r3,.Lscpa1-PARMAREA(%r4) | ||
| 556 | chi %r3,0x00 | ||
| 557 | jne .Lcompmem | ||
| 558 | l %r3,.Lscpa2-PARMAREA(%r13) | ||
| 559 | .Lcompmem: | ||
| 560 | mr %r2,%r1 # mem in MB on 128-bit | ||
| 561 | l %r1,.Lonemb-.LPG1(%r13) | ||
| 562 | mr %r2,%r1 # mem size in bytes in %r3 | ||
| 563 | b .Lfchunk-.LPG1(%r13) | ||
| 564 | |||
| 565 | .align 4 | ||
| 566 | .Lget_ipl_device_addr: | ||
| 567 | .long .Lget_ipl_device | ||
| 568 | .Lpmask: | ||
| 569 | .byte 0 | ||
| 570 | .align 8 | ||
| 571 | .Lpcext:.long 0x00080000,0x80000000 | ||
| 572 | .Lcr: | ||
| 573 | .long 0x00 # place holder for cr0 | ||
| 574 | .Lwaitsclp: | ||
| 575 | .long 0x020A0000 | ||
| 576 | .long .Lsclph | ||
| 577 | .Lrcp: | ||
| 578 | .int 0x00120001 # Read SCP forced code | ||
| 579 | .Lrcp2: | ||
| 580 | .int 0x00020001 # Read SCP code | ||
| 581 | .Lonemb: | ||
| 582 | .int 0x100000 | ||
| 583 | .Lfchunk: | ||
| 584 | |||
| 585 | # | ||
| 586 | # find memory chunks. | ||
| 587 | # | ||
| 588 | lr %r9,%r3 # end of mem | ||
| 589 | mvc __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13) | ||
| 590 | la %r1,1 # test in increments of 128KB | ||
| 591 | sll %r1,17 | ||
| 592 | l %r3,.Lmchunk-.LPG1(%r13) # get pointer to memory_chunk array | ||
| 593 | slr %r4,%r4 # set start of chunk to zero | ||
| 594 | slr %r5,%r5 # set end of chunk to zero | ||
| 595 | slr %r6,%r6 # set access code to zero | ||
| 596 | la %r10, MEMORY_CHUNKS # number of chunks | ||
| 597 | .Lloop: | ||
| 598 | tprot 0(%r5),0 # test protection of first byte | ||
| 599 | ipm %r7 | ||
| 600 | srl %r7,28 | ||
| 601 | clr %r6,%r7 # compare cc with last access code | ||
| 602 | be .Lsame-.LPG1(%r13) | ||
| 603 | b .Lchkmem-.LPG1(%r13) | ||
| 604 | .Lsame: | ||
| 605 | ar %r5,%r1 # add 128KB to end of chunk | ||
| 606 | bno .Lloop-.LPG1(%r13) # r1 < 0x80000000 -> loop | ||
| 607 | .Lchkmem: # > 2GB or tprot got a program check | ||
| 608 | clr %r4,%r5 # chunk size > 0? | ||
| 609 | be .Lchkloop-.LPG1(%r13) | ||
| 610 | st %r4,0(%r3) # store start address of chunk | ||
| 611 | lr %r0,%r5 | ||
| 612 | slr %r0,%r4 | ||
| 613 | st %r0,4(%r3) # store size of chunk | ||
| 614 | st %r6,8(%r3) # store type of chunk | ||
| 615 | la %r3,12(%r3) | ||
| 616 | l %r4,.Lmemsize-.LPG1(%r13) # address of variable memory_size | ||
| 617 | st %r5,0(%r4) # store last end to memory size | ||
| 618 | ahi %r10,-1 # update chunk number | ||
| 619 | .Lchkloop: | ||
| 620 | lr %r6,%r7 # set access code to last cc | ||
| 621 | # we got an exception or we're starting a new | ||
| 622 | # chunk , we must check if we should | ||
| 623 | # still try to find valid memory (if we detected | ||
| 624 | # the amount of available storage), and if we | ||
| 625 | # have chunks left | ||
| 626 | xr %r0,%r0 | ||
| 627 | clr %r0,%r9 # did we detect memory? | ||
| 628 | je .Ldonemem # if not, leave | ||
| 629 | chi %r10,0 # do we have chunks left? | ||
| 630 | je .Ldonemem | ||
| 631 | alr %r5,%r1 # add 128KB to end of chunk | ||
| 632 | lr %r4,%r5 # potential new chunk | ||
| 633 | clr %r5,%r9 # should we go on? | ||
| 634 | jl .Lloop | ||
| 635 | .Ldonemem: | ||
| 636 | l %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags | ||
| 637 | # | ||
| 638 | # find out if we are running under VM | ||
| 639 | # | ||
| 640 | stidp __LC_CPUID # store cpuid | ||
| 641 | tm __LC_CPUID,0xff # running under VM ? | ||
| 642 | bno .Lnovm-.LPG1(%r13) | ||
| 643 | oi 3(%r12),1 # set VM flag | ||
| 644 | .Lnovm: | ||
| 645 | lh %r0,__LC_CPUID+4 # get cpu version | ||
| 646 | chi %r0,0x7490 # running on a P/390 ? | ||
| 647 | bne .Lnop390-.LPG1(%r13) | ||
| 648 | oi 3(%r12),4 # set P/390 flag | ||
| 649 | .Lnop390: | ||
| 650 | |||
| 651 | # | ||
| 652 | # find out if we have an IEEE fpu | ||
| 653 | # | ||
| 654 | mvc __LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13) | ||
| 655 | efpc %r0,0 # test IEEE extract fpc instruction | ||
| 656 | oi 3(%r12),2 # set IEEE fpu flag | ||
| 657 | .Lchkfpu: | ||
| 658 | |||
| 659 | # | ||
| 660 | # find out if we have the CSP instruction | ||
| 661 | # | ||
| 662 | mvc __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13) | ||
| 663 | la %r0,0 | ||
| 664 | lr %r1,%r0 | ||
| 665 | la %r2,4 | ||
| 666 | csp %r0,%r2 # Test CSP instruction | ||
| 667 | oi 3(%r12),8 # set CSP flag | ||
| 668 | .Lchkcsp: | ||
| 669 | |||
| 670 | # | ||
| 671 | # find out if we have the MVPG instruction | ||
| 672 | # | ||
| 673 | mvc __LC_PGM_NEW_PSW(8),.Lpcmvpg-.LPG1(%r13) | ||
| 674 | sr %r0,%r0 | ||
| 675 | la %r1,0 | ||
| 676 | la %r2,0 | ||
| 677 | mvpg %r1,%r2 # Test CSP instruction | ||
| 678 | oi 3(%r12),16 # set MVPG flag | ||
| 679 | .Lchkmvpg: | ||
| 680 | |||
| 681 | # | ||
| 682 | # find out if we have the IDTE instruction | ||
| 683 | # | ||
| 684 | mvc __LC_PGM_NEW_PSW(8),.Lpcidte-.LPG1(%r13) | ||
| 685 | .long 0xb2b10000 # store facility list | ||
| 686 | tm 0xc8,0x08 # check bit for clearing-by-ASCE | ||
| 687 | bno .Lchkidte-.LPG1(%r13) | ||
| 688 | lhi %r1,2094 | ||
| 689 | lhi %r2,0 | ||
| 690 | .long 0xb98e2001 | ||
| 691 | oi 3(%r12),0x80 # set IDTE flag | ||
| 692 | .Lchkidte: | ||
| 693 | |||
| 694 | lpsw .Lentry-.LPG1(13) # jump to _stext in primary-space, | ||
| 695 | # virtual and never return ... | ||
| 696 | .align 8 | ||
| 697 | .Lentry:.long 0x00080000,0x80000000 + _stext | ||
| 698 | .Lctl: .long 0x04b50002 # cr0: various things | ||
| 699 | .long 0 # cr1: primary space segment table | ||
| 700 | .long .Lduct # cr2: dispatchable unit control table | ||
| 701 | .long 0 # cr3: instruction authorization | ||
| 702 | .long 0 # cr4: instruction authorization | ||
| 703 | .long 0xffffffff # cr5: primary-aste origin | ||
| 704 | .long 0 # cr6: I/O interrupts | ||
| 705 | .long 0 # cr7: secondary space segment table | ||
| 706 | .long 0 # cr8: access registers translation | ||
| 707 | .long 0 # cr9: tracing off | ||
| 708 | .long 0 # cr10: tracing off | ||
| 709 | .long 0 # cr11: tracing off | ||
| 710 | .long 0 # cr12: tracing off | ||
| 711 | .long 0 # cr13: home space segment table | ||
| 712 | .long 0xc0000000 # cr14: machine check handling off | ||
| 713 | .long 0 # cr15: linkage stack operations | ||
| 714 | .Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem | ||
| 715 | .Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu | ||
| 716 | .Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp | ||
| 717 | .Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg | ||
| 718 | .Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte | ||
| 719 | .Lmemsize:.long memory_size | ||
| 720 | .Lmchunk:.long memory_chunk | ||
| 721 | .Lmflags:.long machine_flags | ||
| 722 | .Lbss_bgn: .long __bss_start | ||
| 723 | .Lbss_end: .long _end | ||
| 724 | |||
| 725 | .org PARMAREA-64 | ||
| 726 | .Lduct: .long 0,0,0,0,0,0,0,0 | ||
| 727 | .long 0,0,0,0,0,0,0,0 | ||
| 728 | |||
| 729 | # | ||
| 730 | # params at 10400 (setup.h) | ||
| 731 | # | ||
| 732 | .org PARMAREA | ||
| 733 | .global _pstart | ||
| 734 | _pstart: | ||
| 735 | .long 0,0 # IPL_DEVICE | ||
| 736 | .long 0,RAMDISK_ORIGIN # INITRD_START | ||
| 737 | .long 0,RAMDISK_SIZE # INITRD_SIZE | ||
| 738 | |||
| 739 | .org COMMAND_LINE | ||
| 740 | .byte "root=/dev/ram0 ro" | ||
| 741 | .byte 0 | ||
| 742 | .org 0x11000 | ||
| 743 | .Lsccb: | ||
| 744 | .hword 0x1000 # length, one page | ||
| 745 | .byte 0x00,0x00,0x00 | ||
| 746 | .byte 0x80 # variable response bit set | ||
| 747 | .Lsccbr: | ||
| 748 | .hword 0x00 # response code | ||
| 749 | .Lscpincr1: | ||
| 750 | .hword 0x00 | ||
| 751 | .Lscpa1: | ||
| 752 | .byte 0x00 | ||
| 753 | .fill 89,1,0 | ||
| 754 | .Lscpa2: | ||
| 755 | .int 0x00 | ||
| 756 | .Lscpincr2: | ||
| 757 | .quad 0x00 | ||
| 758 | .fill 3984,1,0 | ||
| 759 | .org 0x12000 | ||
| 760 | .global _pend | ||
| 761 | _pend: | ||
| 762 | |||
| 763 | .Lget_ipl_device: | 484 | .Lget_ipl_device: | 
| 764 | basr %r12,0 | 485 | basr %r12,0 | 
| 765 | .LPG2: l %r1,0xb8 # get sid | 486 | .LGID: l %r1,0xb8 # get sid | 
| 766 | sll %r1,15 # test if subchannel is enabled | 487 | sll %r1,15 # test if subchannel is enabled | 
| 767 | srl %r1,31 | 488 | srl %r1,31 | 
| 768 | ltr %r1,%r1 | 489 | ltr %r1,%r1 | 
| 769 | bz 0(%r14) # subchannel disabled | 490 | bz 0(%r14) # subchannel disabled | 
| 770 | l %r1,0xb8 | 491 | l %r1,0xb8 | 
| 771 | la %r5,.Lipl_schib-.LPG2(%r12) | 492 | la %r5,.Lipl_schib-.LGID(%r12) | 
| 772 | stsch 0(%r5) # get schib of subchannel | 493 | stsch 0(%r5) # get schib of subchannel | 
| 773 | bnz 0(%r14) # schib not available | 494 | bnz 0(%r14) # schib not available | 
| 774 | tm 5(%r5),0x01 # devno valid? | 495 | tm 5(%r5),0x01 # devno valid? | 
| 775 | bno 0(%r14) | 496 | bno 0(%r14) | 
| 776 | la %r6,ipl_parameter_flags-.LPG2(%r12) | 497 | la %r6,ipl_parameter_flags-.LGID(%r12) | 
| 777 | oi 3(%r6),0x01 # set flag | 498 | oi 3(%r6),0x01 # set flag | 
| 778 | la %r2,ipl_devno-.LPG2(%r12) | 499 | la %r2,ipl_devno-.LGID(%r12) | 
| 779 | mvc 0(2,%r2),6(%r5) # store devno | 500 | mvc 0(2,%r2),6(%r5) # store devno | 
| 780 | tm 4(%r5),0x80 # qdio capable device? | 501 | tm 4(%r5),0x80 # qdio capable device? | 
| 781 | bno 0(%r14) | 502 | bno 0(%r14) | 
| @@ -816,46 +537,10 @@ ipl_parameter_flags: | |||
| 816 | .globl ipl_devno | 537 | .globl ipl_devno | 
| 817 | ipl_devno: | 538 | ipl_devno: | 
| 818 | .word 0 | 539 | .word 0 | 
| 540 | .endm | ||
| 819 | 541 | ||
| 820 | #ifdef CONFIG_SHARED_KERNEL | 542 | #ifdef CONFIG_ARCH_S390X | 
| 821 | .org 0x100000 | 543 | #include "head64.S" | 
| 544 | #else | ||
| 545 | #include "head31.S" | ||
| 822 | #endif | 546 | #endif | 
| 823 | |||
| 824 | # | ||
| 825 | # startup-code, running in virtual mode | ||
| 826 | # | ||
| 827 | .globl _stext | ||
| 828 | _stext: basr %r13,0 # get base | ||
| 829 | .LPG3: | ||
| 830 | # | ||
| 831 | # Setup stack | ||
| 832 | # | ||
| 833 | l %r15,.Linittu-.LPG3(%r13) | ||
| 834 | mvc __LC_CURRENT(4),__TI_task(%r15) | ||
| 835 | ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE | ||
| 836 | st %r15,__LC_KERNEL_STACK # set end of kernel stack | ||
| 837 | ahi %r15,-96 | ||
| 838 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain | ||
| 839 | |||
| 840 | # check control registers | ||
| 841 | stctl %c0,%c15,0(%r15) | ||
| 842 | oi 2(%r15),0x40 # enable sigp emergency signal | ||
| 843 | oi 0(%r15),0x10 # switch on low address protection | ||
| 844 | lctl %c0,%c15,0(%r15) | ||
| 845 | |||
| 846 | # | ||
| 847 | lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess | ||
| 848 | l %r14,.Lstart-.LPG3(%r13) | ||
| 849 | basr %r14,%r14 # call start_kernel | ||
| 850 | # | ||
| 851 | # We returned from start_kernel ?!? PANIK | ||
| 852 | # | ||
| 853 | basr %r13,0 | ||
| 854 | lpsw .Ldw-.(%r13) # load disabled wait psw | ||
| 855 | # | ||
| 856 | .align 8 | ||
| 857 | .Ldw: .long 0x000a0000,0x00000000 | ||
| 858 | .Linittu: .long init_thread_union | ||
| 859 | .Lstart: .long start_kernel | ||
| 860 | .Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | ||
| 861 | |||
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S new file mode 100644 index 000000000000..2d3b089bfb83 --- /dev/null +++ b/arch/s390/kernel/head31.S  | |||
| @@ -0,0 +1,336 @@ | |||
| 1 | /* | ||
| 2 | * arch/s390/kernel/head31.S | ||
| 3 | * | ||
| 4 | * (C) Copyright IBM Corp. 2005 | ||
| 5 | * | ||
| 6 | * Author(s): Hartmut Penner <hp@de.ibm.com> | ||
| 7 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | ||
| 8 | * Rob van der Heij <rvdhei@iae.nl> | ||
| 9 | * Heiko Carstens <heiko.carstens@de.ibm.com> | ||
| 10 | * | ||
| 11 | */ | ||
| 12 | |||
| 13 | # | ||
| 14 | # startup-code at 0x10000, running in absolute addressing mode | ||
| 15 | # this is called either by the ipl loader or directly by PSW restart | ||
| 16 | # or linload or SALIPL | ||
| 17 | # | ||
| 18 | .org 0x10000 | ||
| 19 | startup:basr %r13,0 # get base | ||
| 20 | .LPG1: l %r1, .Lget_ipl_device_addr-.LPG1(%r13) | ||
| 21 | basr %r14, %r1 | ||
| 22 | lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers | ||
| 23 | la %r12,_pstart-.LPG1(%r13) # pointer to parameter area | ||
| 24 | # move IPL device to lowcore | ||
| 25 | mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12) | ||
| 26 | |||
| 27 | # | ||
| 28 | # clear bss memory | ||
| 29 | # | ||
| 30 | l %r2,.Lbss_bgn-.LPG1(%r13) # start of bss | ||
| 31 | l %r3,.Lbss_end-.LPG1(%r13) # end of bss | ||
| 32 | sr %r3,%r2 # length of bss | ||
| 33 | sr %r4,%r4 | ||
| 34 | sr %r5,%r5 # set src,length and pad to zero | ||
| 35 | sr %r0,%r0 | ||
| 36 | mvcle %r2,%r4,0 # clear mem | ||
| 37 | jo .-4 # branch back, if not finish | ||
| 38 | |||
| 39 | l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word | ||
| 40 | .Lservicecall: | ||
| 41 | stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts | ||
| 42 | |||
| 43 | stctl %r0, %r0,.Lcr-.LPG1(%r13) # get cr0 | ||
| 44 | la %r1,0x200 # set bit 22 | ||
| 45 | o %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1 | ||
| 46 | st %r1,.Lcr-.LPG1(%r13) | ||
| 47 | lctl %r0, %r0,.Lcr-.LPG1(%r13) # load modified cr0 | ||
| 48 | |||
| 49 | mvc __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw | ||
| 50 | la %r1, .Lsclph-.LPG1(%r13) | ||
| 51 | a %r1,__LC_EXT_NEW_PSW+4 # set handler | ||
| 52 | st %r1,__LC_EXT_NEW_PSW+4 | ||
| 53 | |||
| 54 | la %r4,_pstart-.LPG1(%r13) # %r4 is our index for sccb stuff | ||
| 55 | la %r1, .Lsccb-PARMAREA(%r4) # our sccb | ||
| 56 | .insn rre,0xb2200000,%r2,%r1 # service call | ||
| 57 | ipm %r1 | ||
| 58 | srl %r1,28 # get cc code | ||
| 59 | xr %r3, %r3 | ||
| 60 | chi %r1,3 | ||
| 61 | be .Lfchunk-.LPG1(%r13) # leave | ||
| 62 | chi %r1,2 | ||
| 63 | be .Lservicecall-.LPG1(%r13) | ||
| 64 | lpsw .Lwaitsclp-.LPG1(%r13) | ||
| 65 | .Lsclph: | ||
| 66 | lh %r1,.Lsccbr-PARMAREA(%r4) | ||
| 67 | chi %r1,0x10 # 0x0010 is the sucess code | ||
| 68 | je .Lprocsccb # let's process the sccb | ||
| 69 | chi %r1,0x1f0 | ||
| 70 | bne .Lfchunk-.LPG1(%r13) # unhandled error code | ||
| 71 | c %r2, .Lrcp-.LPG1(%r13) # Did we try Read SCP forced | ||
| 72 | bne .Lfchunk-.LPG1(%r13) # if no, give up | ||
| 73 | l %r2, .Lrcp2-.LPG1(%r13) # try with Read SCP | ||
| 74 | b .Lservicecall-.LPG1(%r13) | ||
| 75 | .Lprocsccb: | ||
| 76 | lhi %r1,0 | ||
| 77 | icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 | ||
| 78 | jnz .Lscnd | ||
| 79 | lhi %r1,0x800 # otherwise report 2GB | ||
| 80 | .Lscnd: | ||
| 81 | lhi %r3,0x800 # limit reported memory size to 2GB | ||
| 82 | cr %r1,%r3 | ||
| 83 | jl .Lno2gb | ||
| 84 | lr %r1,%r3 | ||
| 85 | .Lno2gb: | ||
| 86 | xr %r3,%r3 # same logic | ||
| 87 | ic %r3,.Lscpa1-PARMAREA(%r4) | ||
| 88 | chi %r3,0x00 | ||
| 89 | jne .Lcompmem | ||
| 90 | l %r3,.Lscpa2-PARMAREA(%r13) | ||
| 91 | .Lcompmem: | ||
| 92 | mr %r2,%r1 # mem in MB on 128-bit | ||
| 93 | l %r1,.Lonemb-.LPG1(%r13) | ||
| 94 | mr %r2,%r1 # mem size in bytes in %r3 | ||
| 95 | b .Lfchunk-.LPG1(%r13) | ||
| 96 | |||
| 97 | .align 4 | ||
| 98 | .Lget_ipl_device_addr: | ||
| 99 | .long .Lget_ipl_device | ||
| 100 | .Lpmask: | ||
| 101 | .byte 0 | ||
| 102 | .align 8 | ||
| 103 | .Lpcext:.long 0x00080000,0x80000000 | ||
| 104 | .Lcr: | ||
| 105 | .long 0x00 # place holder for cr0 | ||
| 106 | .Lwaitsclp: | ||
| 107 | .long 0x010a0000,0x80000000 + .Lsclph | ||
| 108 | .Lrcp: | ||
| 109 | .int 0x00120001 # Read SCP forced code | ||
| 110 | .Lrcp2: | ||
| 111 | .int 0x00020001 # Read SCP code | ||
| 112 | .Lonemb: | ||
| 113 | .int 0x100000 | ||
| 114 | .Lfchunk: | ||
| 115 | |||
| 116 | # | ||
| 117 | # find memory chunks. | ||
| 118 | # | ||
| 119 | lr %r9,%r3 # end of mem | ||
| 120 | mvc __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13) | ||
| 121 | la %r1,1 # test in increments of 128KB | ||
| 122 | sll %r1,17 | ||
| 123 | l %r3,.Lmchunk-.LPG1(%r13) # get pointer to memory_chunk array | ||
| 124 | slr %r4,%r4 # set start of chunk to zero | ||
| 125 | slr %r5,%r5 # set end of chunk to zero | ||
| 126 | slr %r6,%r6 # set access code to zero | ||
| 127 | la %r10, MEMORY_CHUNKS # number of chunks | ||
| 128 | .Lloop: | ||
| 129 | tprot 0(%r5),0 # test protection of first byte | ||
| 130 | ipm %r7 | ||
| 131 | srl %r7,28 | ||
| 132 | clr %r6,%r7 # compare cc with last access code | ||
| 133 | be .Lsame-.LPG1(%r13) | ||
| 134 | b .Lchkmem-.LPG1(%r13) | ||
| 135 | .Lsame: | ||
| 136 | ar %r5,%r1 # add 128KB to end of chunk | ||
| 137 | bno .Lloop-.LPG1(%r13) # r1 < 0x80000000 -> loop | ||
| 138 | .Lchkmem: # > 2GB or tprot got a program check | ||
| 139 | clr %r4,%r5 # chunk size > 0? | ||
| 140 | be .Lchkloop-.LPG1(%r13) | ||
| 141 | st %r4,0(%r3) # store start address of chunk | ||
| 142 | lr %r0,%r5 | ||
| 143 | slr %r0,%r4 | ||
| 144 | st %r0,4(%r3) # store size of chunk | ||
| 145 | st %r6,8(%r3) # store type of chunk | ||
| 146 | la %r3,12(%r3) | ||
| 147 | l %r4,.Lmemsize-.LPG1(%r13) # address of variable memory_size | ||
| 148 | st %r5,0(%r4) # store last end to memory size | ||
| 149 | ahi %r10,-1 # update chunk number | ||
| 150 | .Lchkloop: | ||
| 151 | lr %r6,%r7 # set access code to last cc | ||
| 152 | # we got an exception or we're starting a new | ||
| 153 | # chunk , we must check if we should | ||
| 154 | # still try to find valid memory (if we detected | ||
| 155 | # the amount of available storage), and if we | ||
| 156 | # have chunks left | ||
| 157 | xr %r0,%r0 | ||
| 158 | clr %r0,%r9 # did we detect memory? | ||
| 159 | je .Ldonemem # if not, leave | ||
| 160 | chi %r10,0 # do we have chunks left? | ||
| 161 | je .Ldonemem | ||
| 162 | alr %r5,%r1 # add 128KB to end of chunk | ||
| 163 | lr %r4,%r5 # potential new chunk | ||
| 164 | clr %r5,%r9 # should we go on? | ||
| 165 | jl .Lloop | ||
| 166 | .Ldonemem: | ||
| 167 | l %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags | ||
| 168 | # | ||
| 169 | # find out if we are running under VM | ||
| 170 | # | ||
| 171 | stidp __LC_CPUID # store cpuid | ||
| 172 | tm __LC_CPUID,0xff # running under VM ? | ||
| 173 | bno .Lnovm-.LPG1(%r13) | ||
| 174 | oi 3(%r12),1 # set VM flag | ||
| 175 | .Lnovm: | ||
| 176 | lh %r0,__LC_CPUID+4 # get cpu version | ||
| 177 | chi %r0,0x7490 # running on a P/390 ? | ||
| 178 | bne .Lnop390-.LPG1(%r13) | ||
| 179 | oi 3(%r12),4 # set P/390 flag | ||
| 180 | .Lnop390: | ||
| 181 | |||
| 182 | # | ||
| 183 | # find out if we have an IEEE fpu | ||
| 184 | # | ||
| 185 | mvc __LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13) | ||
| 186 | efpc %r0,0 # test IEEE extract fpc instruction | ||
| 187 | oi 3(%r12),2 # set IEEE fpu flag | ||
| 188 | .Lchkfpu: | ||
| 189 | |||
| 190 | # | ||
| 191 | # find out if we have the CSP instruction | ||
| 192 | # | ||
| 193 | mvc __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13) | ||
| 194 | la %r0,0 | ||
| 195 | lr %r1,%r0 | ||
| 196 | la %r2,4 | ||
| 197 | csp %r0,%r2 # Test CSP instruction | ||
| 198 | oi 3(%r12),8 # set CSP flag | ||
| 199 | .Lchkcsp: | ||
| 200 | |||
| 201 | # | ||
| 202 | # find out if we have the MVPG instruction | ||
| 203 | # | ||
| 204 | mvc __LC_PGM_NEW_PSW(8),.Lpcmvpg-.LPG1(%r13) | ||
| 205 | sr %r0,%r0 | ||
| 206 | la %r1,0 | ||
| 207 | la %r2,0 | ||
| 208 | mvpg %r1,%r2 # Test CSP instruction | ||
| 209 | oi 3(%r12),16 # set MVPG flag | ||
| 210 | .Lchkmvpg: | ||
| 211 | |||
| 212 | # | ||
| 213 | # find out if we have the IDTE instruction | ||
| 214 | # | ||
| 215 | mvc __LC_PGM_NEW_PSW(8),.Lpcidte-.LPG1(%r13) | ||
| 216 | .long 0xb2b10000 # store facility list | ||
| 217 | tm 0xc8,0x08 # check bit for clearing-by-ASCE | ||
| 218 | bno .Lchkidte-.LPG1(%r13) | ||
| 219 | lhi %r1,2094 | ||
| 220 | lhi %r2,0 | ||
| 221 | .long 0xb98e2001 | ||
| 222 | oi 3(%r12),0x80 # set IDTE flag | ||
| 223 | .Lchkidte: | ||
| 224 | |||
| 225 | lpsw .Lentry-.LPG1(13) # jump to _stext in primary-space, | ||
| 226 | # virtual and never return ... | ||
| 227 | .align 8 | ||
| 228 | .Lentry:.long 0x00080000,0x80000000 + _stext | ||
| 229 | .Lctl: .long 0x04b50002 # cr0: various things | ||
| 230 | .long 0 # cr1: primary space segment table | ||
| 231 | .long .Lduct # cr2: dispatchable unit control table | ||
| 232 | .long 0 # cr3: instruction authorization | ||
| 233 | .long 0 # cr4: instruction authorization | ||
| 234 | .long 0xffffffff # cr5: primary-aste origin | ||
| 235 | .long 0 # cr6: I/O interrupts | ||
| 236 | .long 0 # cr7: secondary space segment table | ||
| 237 | .long 0 # cr8: access registers translation | ||
| 238 | .long 0 # cr9: tracing off | ||
| 239 | .long 0 # cr10: tracing off | ||
| 240 | .long 0 # cr11: tracing off | ||
| 241 | .long 0 # cr12: tracing off | ||
| 242 | .long 0 # cr13: home space segment table | ||
| 243 | .long 0xc0000000 # cr14: machine check handling off | ||
| 244 | .long 0 # cr15: linkage stack operations | ||
| 245 | .Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem | ||
| 246 | .Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu | ||
| 247 | .Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp | ||
| 248 | .Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg | ||
| 249 | .Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte | ||
| 250 | .Lmemsize:.long memory_size | ||
| 251 | .Lmchunk:.long memory_chunk | ||
| 252 | .Lmflags:.long machine_flags | ||
| 253 | .Lbss_bgn: .long __bss_start | ||
| 254 | .Lbss_end: .long _end | ||
| 255 | |||
| 256 | .org PARMAREA-64 | ||
| 257 | .Lduct: .long 0,0,0,0,0,0,0,0 | ||
| 258 | .long 0,0,0,0,0,0,0,0 | ||
| 259 | |||
| 260 | # | ||
| 261 | # params at 10400 (setup.h) | ||
| 262 | # | ||
| 263 | .org PARMAREA | ||
| 264 | .global _pstart | ||
| 265 | _pstart: | ||
| 266 | .long 0,0 # IPL_DEVICE | ||
| 267 | .long 0,RAMDISK_ORIGIN # INITRD_START | ||
| 268 | .long 0,RAMDISK_SIZE # INITRD_SIZE | ||
| 269 | |||
| 270 | .org COMMAND_LINE | ||
| 271 | .byte "root=/dev/ram0 ro" | ||
| 272 | .byte 0 | ||
| 273 | .org 0x11000 | ||
| 274 | .Lsccb: | ||
| 275 | .hword 0x1000 # length, one page | ||
| 276 | .byte 0x00,0x00,0x00 | ||
| 277 | .byte 0x80 # variable response bit set | ||
| 278 | .Lsccbr: | ||
| 279 | .hword 0x00 # response code | ||
| 280 | .Lscpincr1: | ||
| 281 | .hword 0x00 | ||
| 282 | .Lscpa1: | ||
| 283 | .byte 0x00 | ||
| 284 | .fill 89,1,0 | ||
| 285 | .Lscpa2: | ||
| 286 | .int 0x00 | ||
| 287 | .Lscpincr2: | ||
| 288 | .quad 0x00 | ||
| 289 | .fill 3984,1,0 | ||
| 290 | .org 0x12000 | ||
| 291 | .global _pend | ||
| 292 | _pend: | ||
| 293 | |||
| 294 | GET_IPL_DEVICE | ||
| 295 | |||
| 296 | #ifdef CONFIG_SHARED_KERNEL | ||
| 297 | .org 0x100000 | ||
| 298 | #endif | ||
| 299 | |||
| 300 | # | ||
| 301 | # startup-code, running in virtual mode | ||
| 302 | # | ||
| 303 | .globl _stext | ||
| 304 | _stext: basr %r13,0 # get base | ||
| 305 | .LPG3: | ||
| 306 | # | ||
| 307 | # Setup stack | ||
| 308 | # | ||
| 309 | l %r15,.Linittu-.LPG3(%r13) | ||
| 310 | mvc __LC_CURRENT(4),__TI_task(%r15) | ||
| 311 | ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE | ||
| 312 | st %r15,__LC_KERNEL_STACK # set end of kernel stack | ||
| 313 | ahi %r15,-96 | ||
| 314 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain | ||
| 315 | |||
| 316 | # check control registers | ||
| 317 | stctl %c0,%c15,0(%r15) | ||
| 318 | oi 2(%r15),0x40 # enable sigp emergency signal | ||
| 319 | oi 0(%r15),0x10 # switch on low address protection | ||
| 320 | lctl %c0,%c15,0(%r15) | ||
| 321 | |||
| 322 | # | ||
| 323 | lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess | ||
| 324 | l %r14,.Lstart-.LPG3(%r13) | ||
| 325 | basr %r14,%r14 # call start_kernel | ||
| 326 | # | ||
| 327 | # We returned from start_kernel ?!? PANIK | ||
| 328 | # | ||
| 329 | basr %r13,0 | ||
| 330 | lpsw .Ldw-.(%r13) # load disabled wait psw | ||
| 331 | # | ||
| 332 | .align 8 | ||
| 333 | .Ldw: .long 0x000a0000,0x00000000 | ||
| 334 | .Linittu:.long init_thread_union | ||
| 335 | .Lstart:.long start_kernel | ||
| 336 | .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 193aafa72f54..f08c06f45d5c 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S  | |||
| @@ -1,482 +1,17 @@ | |||
| 1 | /* | 1 | /* | 
| 2 | * arch/s390/kernel/head.S | 2 | * arch/s390/kernel/head64.S | 
| 3 | * | 3 | * | 
| 4 | * S390 version | 4 | * (C) Copyright IBM Corp. 1999,2005 | 
| 5 | * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation | 5 | * | 
| 6 | * Author(s): Hartmut Penner (hp@de.ibm.com), | 6 | * Author(s): Hartmut Penner <hp@de.ibm.com> | 
| 7 | * Martin Schwidefsky (schwidefsky@de.ibm.com), | 7 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 
| 8 | * Rob van der Heij (rvdhei@iae.nl) | 8 | * Rob van der Heij <rvdhei@iae.nl> | 
| 9 | * Heiko Carstens <heiko.carstens@de.ibm.com> | ||
| 9 | * | 10 | * | 
| 10 | * There are 5 different IPL methods | ||
| 11 | * 1) load the image directly into ram at address 0 and do an PSW restart | ||
| 12 | * 2) linload will load the image from address 0x10000 to memory 0x10000 | ||
| 13 | * and start the code thru LPSW 0x0008000080010000 (VM only, deprecated) | ||
| 14 | * 3) generate the tape ipl header, store the generated image on a tape | ||
| 15 | * and ipl from it | ||
| 16 | * In case of SL tape you need to IPL 5 times to get past VOL1 etc | ||
| 17 | * 4) generate the vm reader ipl header, move the generated image to the | ||
| 18 | * VM reader (use option NOH!) and do a ipl from reader (VM only) | ||
| 19 | * 5) direct call of start by the SALIPL loader | ||
| 20 | * We use the cpuid to distinguish between VM and native ipl | ||
| 21 | * params for kernel are pushed to 0x10400 (see setup.h) | ||
| 22 | |||
| 23 | Changes: | ||
| 24 | Okt 25 2000 <rvdheij@iae.nl> | ||
| 25 | added code to skip HDR and EOF to allow SL tape IPL (5 retries) | ||
| 26 | changed first CCW from rewind to backspace block | ||
| 27 | |||
| 28 | */ | 11 | */ | 
| 29 | 12 | ||
| 30 | #include <linux/config.h> | ||
| 31 | #include <asm/setup.h> | ||
| 32 | #include <asm/lowcore.h> | ||
| 33 | #include <asm/asm-offsets.h> | ||
| 34 | #include <asm/thread_info.h> | ||
| 35 | #include <asm/page.h> | ||
| 36 | |||
| 37 | #ifndef CONFIG_IPL | ||
| 38 | .org 0 | ||
| 39 | .long 0x00080000,0x80000000+startup # Just a restart PSW | ||
| 40 | #else | ||
| 41 | #ifdef CONFIG_IPL_TAPE | ||
| 42 | #define IPL_BS 1024 | ||
| 43 | .org 0 | ||
| 44 | .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded | ||
| 45 | .long 0x27000000,0x60000001 # by ipl to addresses 0-23. | ||
| 46 | .long 0x02000000,0x20000000+IPL_BS # (a PSW and two CCWs). | ||
| 47 | .long 0x00000000,0x00000000 # external old psw | ||
| 48 | .long 0x00000000,0x00000000 # svc old psw | ||
| 49 | .long 0x00000000,0x00000000 # program check old psw | ||
| 50 | .long 0x00000000,0x00000000 # machine check old psw | ||
| 51 | .long 0x00000000,0x00000000 # io old psw | ||
| 52 | .long 0x00000000,0x00000000 | ||
| 53 | .long 0x00000000,0x00000000 | ||
| 54 | .long 0x00000000,0x00000000 | ||
| 55 | .long 0x000a0000,0x00000058 # external new psw | ||
| 56 | .long 0x000a0000,0x00000060 # svc new psw | ||
| 57 | .long 0x000a0000,0x00000068 # program check new psw | ||
| 58 | .long 0x000a0000,0x00000070 # machine check new psw | ||
| 59 | .long 0x00080000,0x80000000+.Lioint # io new psw | ||
| 60 | |||
| 61 | .org 0x100 | ||
| 62 | # | ||
| 63 | # subroutine for loading from tape | ||
| 64 | # Paramters: | ||
| 65 | # R1 = device number | ||
| 66 | # R2 = load address | ||
| 67 | .Lloader: | ||
| 68 | st %r14,.Lldret | ||
| 69 | la %r3,.Lorbread # r3 = address of orb | ||
| 70 | la %r5,.Lirb # r5 = address of irb | ||
| 71 | st %r2,.Lccwread+4 # initialize CCW data addresses | ||
| 72 | lctl %c6,%c6,.Lcr6 | ||
| 73 | slr %r2,%r2 | ||
| 74 | .Lldlp: | ||
| 75 | la %r6,3 # 3 retries | ||
| 76 | .Lssch: | ||
| 77 | ssch 0(%r3) # load chunk of IPL_BS bytes | ||
| 78 | bnz .Llderr | ||
| 79 | .Lw4end: | ||
| 80 | bas %r14,.Lwait4io | ||
| 81 | tm 8(%r5),0x82 # do we have a problem ? | ||
| 82 | bnz .Lrecov | ||
| 83 | slr %r7,%r7 | ||
| 84 | icm %r7,3,10(%r5) # get residual count | ||
| 85 | lcr %r7,%r7 | ||
| 86 | la %r7,IPL_BS(%r7) # IPL_BS-residual=#bytes read | ||
| 87 | ar %r2,%r7 # add to total size | ||
| 88 | tm 8(%r5),0x01 # found a tape mark ? | ||
| 89 | bnz .Ldone | ||
| 90 | l %r0,.Lccwread+4 # update CCW data addresses | ||
| 91 | ar %r0,%r7 | ||
| 92 | st %r0,.Lccwread+4 | ||
| 93 | b .Lldlp | ||
| 94 | .Ldone: | ||
| 95 | l %r14,.Lldret | ||
| 96 | br %r14 # r2 contains the total size | ||
| 97 | .Lrecov: | ||
| 98 | bas %r14,.Lsense # do the sensing | ||
| 99 | bct %r6,.Lssch # dec. retry count & branch | ||
| 100 | b .Llderr | ||
| 101 | # | ||
| 102 | # Sense subroutine | ||
| 103 | # | ||
| 104 | .Lsense: | ||
| 105 | st %r14,.Lsnsret | ||
| 106 | la %r7,.Lorbsense | ||
| 107 | ssch 0(%r7) # start sense command | ||
| 108 | bnz .Llderr | ||
| 109 | bas %r14,.Lwait4io | ||
| 110 | l %r14,.Lsnsret | ||
| 111 | tm 8(%r5),0x82 # do we have a problem ? | ||
| 112 | bnz .Llderr | ||
| 113 | br %r14 | ||
| 114 | # | ||
| 115 | # Wait for interrupt subroutine | ||
| 116 | # | ||
| 117 | .Lwait4io: | ||
| 118 | lpsw .Lwaitpsw | ||
| 119 | .Lioint: | ||
| 120 | c %r1,0xb8 # compare subchannel number | ||
| 121 | bne .Lwait4io | ||
| 122 | tsch 0(%r5) | ||
| 123 | slr %r0,%r0 | ||
| 124 | tm 8(%r5),0x82 # do we have a problem ? | ||
| 125 | bnz .Lwtexit | ||
| 126 | tm 8(%r5),0x04 # got device end ? | ||
| 127 | bz .Lwait4io | ||
| 128 | .Lwtexit: | ||
| 129 | br %r14 | ||
| 130 | .Llderr: | ||
| 131 | lpsw .Lcrash | ||
| 132 | |||
| 133 | .align 8 | ||
| 134 | .Lorbread: | ||
| 135 | .long 0x00000000,0x0080ff00,.Lccwread | ||
| 136 | .align 8 | ||
| 137 | .Lorbsense: | ||
| 138 | .long 0x00000000,0x0080ff00,.Lccwsense | ||
| 139 | .align 8 | ||
| 140 | .Lccwread: | ||
| 141 | .long 0x02200000+IPL_BS,0x00000000 | ||
| 142 | .Lccwsense: | ||
| 143 | .long 0x04200001,0x00000000 | ||
| 144 | .Lwaitpsw: | ||
| 145 | .long 0x020a0000,0x80000000+.Lioint | ||
| 146 | |||
| 147 | .Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | ||
| 148 | .Lcr6: .long 0xff000000 | ||
| 149 | .align 8 | ||
| 150 | .Lcrash:.long 0x000a0000,0x00000000 | ||
| 151 | .Lldret:.long 0 | ||
| 152 | .Lsnsret: .long 0 | ||
| 153 | #endif /* CONFIG_IPL_TAPE */ | ||
| 154 | |||
| 155 | #ifdef CONFIG_IPL_VM | ||
| 156 | #define IPL_BS 0x730 | ||
| 157 | .org 0 | ||
| 158 | .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded | ||
| 159 | .long 0x02000018,0x60000050 # by ipl to addresses 0-23. | ||
| 160 | .long 0x02000068,0x60000050 # (a PSW and two CCWs). | ||
| 161 | .fill 80-24,1,0x40 # bytes 24-79 are discarded !! | ||
| 162 | .long 0x020000f0,0x60000050 # The next 160 byte are loaded | ||
| 163 | .long 0x02000140,0x60000050 # to addresses 0x18-0xb7 | ||
| 164 | .long 0x02000190,0x60000050 # They form the continuation | ||
| 165 | .long 0x020001e0,0x60000050 # of the CCW program started | ||
| 166 | .long 0x02000230,0x60000050 # by ipl and load the range | ||
| 167 | .long 0x02000280,0x60000050 # 0x0f0-0x730 from the image | ||
| 168 | .long 0x020002d0,0x60000050 # to the range 0x0f0-0x730 | ||
| 169 | .long 0x02000320,0x60000050 # in memory. At the end of | ||
| 170 | .long 0x02000370,0x60000050 # the channel program the PSW | ||
| 171 | .long 0x020003c0,0x60000050 # at location 0 is loaded. | ||
| 172 | .long 0x02000410,0x60000050 # Initial processing starts | ||
| 173 | .long 0x02000460,0x60000050 # at 0xf0 = iplstart. | ||
| 174 | .long 0x020004b0,0x60000050 | ||
| 175 | .long 0x02000500,0x60000050 | ||
| 176 | .long 0x02000550,0x60000050 | ||
| 177 | .long 0x020005a0,0x60000050 | ||
| 178 | .long 0x020005f0,0x60000050 | ||
| 179 | .long 0x02000640,0x60000050 | ||
| 180 | .long 0x02000690,0x60000050 | ||
| 181 | .long 0x020006e0,0x20000050 | ||
| 182 | |||
| 183 | .org 0xf0 | ||
| 184 | # | ||
| 185 | # subroutine for loading cards from the reader | ||
| 186 | # | ||
| 187 | .Lloader: | ||
| 188 | la %r3,.Lorb # r2 = address of orb into r2 | ||
| 189 | la %r5,.Lirb # r4 = address of irb | ||
| 190 | la %r6,.Lccws | ||
| 191 | la %r7,20 | ||
| 192 | .Linit: | ||
| 193 | st %r2,4(%r6) # initialize CCW data addresses | ||
| 194 | la %r2,0x50(%r2) | ||
| 195 | la %r6,8(%r6) | ||
| 196 | bct 7,.Linit | ||
| 197 | |||
| 198 | lctl %c6,%c6,.Lcr6 # set IO subclass mask | ||
| 199 | slr %r2,%r2 | ||
| 200 | .Lldlp: | ||
| 201 | ssch 0(%r3) # load chunk of 1600 bytes | ||
| 202 | bnz .Llderr | ||
| 203 | .Lwait4irq: | ||
| 204 | mvc 0x78(8),.Lnewpsw # set up IO interrupt psw | ||
| 205 | lpsw .Lwaitpsw | ||
| 206 | .Lioint: | ||
| 207 | c %r1,0xb8 # compare subchannel number | ||
| 208 | bne .Lwait4irq | ||
| 209 | tsch 0(%r5) | ||
| 210 | |||
| 211 | slr %r0,%r0 | ||
| 212 | ic %r0,8(%r5) # get device status | ||
| 213 | chi %r0,8 # channel end ? | ||
| 214 | be .Lcont | ||
| 215 | chi %r0,12 # channel end + device end ? | ||
| 216 | be .Lcont | ||
| 217 | |||
| 218 | l %r0,4(%r5) | ||
| 219 | s %r0,8(%r3) # r0/8 = number of ccws executed | ||
| 220 | mhi %r0,10 # *10 = number of bytes in ccws | ||
| 221 | lh %r3,10(%r5) # get residual count | ||
| 222 | sr %r0,%r3 # #ccws*80-residual=#bytes read | ||
| 223 | ar %r2,%r0 | ||
| 224 | |||
| 225 | br %r14 # r2 contains the total size | ||
| 226 | |||
| 227 | .Lcont: | ||
| 228 | ahi %r2,0x640 # add 0x640 to total size | ||
| 229 | la %r6,.Lccws | ||
| 230 | la %r7,20 | ||
| 231 | .Lincr: | ||
| 232 | l %r0,4(%r6) # update CCW data addresses | ||
| 233 | ahi %r0,0x640 | ||
| 234 | st %r0,4(%r6) | ||
| 235 | ahi %r6,8 | ||
| 236 | bct 7,.Lincr | ||
| 237 | |||
| 238 | b .Lldlp | ||
| 239 | .Llderr: | ||
| 240 | lpsw .Lcrash | ||
| 241 | |||
| 242 | .align 8 | ||
| 243 | .Lorb: .long 0x00000000,0x0080ff00,.Lccws | ||
| 244 | .Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | ||
| 245 | .Lcr6: .long 0xff000000 | ||
| 246 | .Lloadp:.long 0,0 | ||
| 247 | .align 8 | ||
| 248 | .Lcrash:.long 0x000a0000,0x00000000 | ||
| 249 | .Lnewpsw: | ||
| 250 | .long 0x00080000,0x80000000+.Lioint | ||
| 251 | .Lwaitpsw: | ||
| 252 | .long 0x020a0000,0x80000000+.Lioint | ||
| 253 | |||
| 254 | .align 8 | ||
| 255 | .Lccws: .rept 19 | ||
| 256 | .long 0x02600050,0x00000000 | ||
| 257 | .endr | ||
| 258 | .long 0x02200050,0x00000000 | ||
| 259 | #endif /* CONFIG_IPL_VM */ | ||
| 260 | |||
| 261 | iplstart: | ||
| 262 | lh %r1,0xb8 # test if subchannel number | ||
| 263 | bct %r1,.Lnoload # is valid | ||
| 264 | l %r1,0xb8 # load ipl subchannel number | ||
| 265 | la %r2,IPL_BS # load start address | ||
| 266 | bas %r14,.Lloader # load rest of ipl image | ||
| 267 | larl %r12,_pstart # pointer to parameter area | ||
| 268 | st %r1,IPL_DEVICE+4-PARMAREA(%r12) # store ipl device number | ||
| 269 | |||
| 270 | # | ||
| 271 | # load parameter file from ipl device | ||
| 272 | # | 13 | # | 
| 273 | .Lagain1: | 14 | # startup-code at 0x10000, running in absolute addressing mode | 
| 274 | l %r2,INITRD_START+4-PARMAREA(%r12)# use ramdisk location as temp | ||
| 275 | bas %r14,.Lloader # load parameter file | ||
| 276 | ltr %r2,%r2 # got anything ? | ||
| 277 | bz .Lnopf | ||
| 278 | chi %r2,895 | ||
| 279 | bnh .Lnotrunc | ||
| 280 | la %r2,895 | ||
| 281 | .Lnotrunc: | ||
| 282 | l %r4,INITRD_START+4-PARMAREA(%r12) | ||
| 283 | clc 0(3,%r4),.L_hdr # if it is HDRx | ||
| 284 | bz .Lagain1 # skip dataset header | ||
| 285 | clc 0(3,%r4),.L_eof # if it is EOFx | ||
| 286 | bz .Lagain1 # skip dateset trailer | ||
| 287 | la %r5,0(%r4,%r2) | ||
| 288 | lr %r3,%r2 | ||
| 289 | .Lidebc: | ||
| 290 | tm 0(%r5),0x80 # high order bit set ? | ||
| 291 | bo .Ldocv # yes -> convert from EBCDIC | ||
| 292 | ahi %r5,-1 | ||
| 293 | bct %r3,.Lidebc | ||
| 294 | b .Lnocv | ||
| 295 | .Ldocv: | ||
| 296 | l %r3,.Lcvtab | ||
| 297 | tr 0(256,%r4),0(%r3) # convert parameters to ascii | ||
| 298 | tr 256(256,%r4),0(%r3) | ||
| 299 | tr 512(256,%r4),0(%r3) | ||
| 300 | tr 768(122,%r4),0(%r3) | ||
| 301 | .Lnocv: la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line | ||
| 302 | mvc 0(256,%r3),0(%r4) | ||
| 303 | mvc 256(256,%r3),256(%r4) | ||
| 304 | mvc 512(256,%r3),512(%r4) | ||
| 305 | mvc 768(122,%r3),768(%r4) | ||
| 306 | slr %r0,%r0 | ||
| 307 | b .Lcntlp | ||
| 308 | .Ldelspc: | ||
| 309 | ic %r0,0(%r2,%r3) | ||
| 310 | chi %r0,0x20 # is it a space ? | ||
| 311 | be .Lcntlp | ||
| 312 | ahi %r2,1 | ||
| 313 | b .Leolp | ||
| 314 | .Lcntlp: | ||
| 315 | brct %r2,.Ldelspc | ||
| 316 | .Leolp: | ||
| 317 | slr %r0,%r0 | ||
| 318 | stc %r0,0(%r2,%r3) # terminate buffer | ||
| 319 | .Lnopf: | ||
| 320 | |||
| 321 | # | ||
| 322 | # load ramdisk from ipl device | ||
| 323 | # | ||
| 324 | .Lagain2: | ||
| 325 | l %r2,INITRD_START+4-PARMAREA(%r12)# load adr. of ramdisk | ||
| 326 | bas %r14,.Lloader # load ramdisk | ||
| 327 | st %r2,INITRD_SIZE+4-PARMAREA(%r12) # store size of ramdisk | ||
| 328 | ltr %r2,%r2 | ||
| 329 | bnz .Lrdcont | ||
| 330 | st %r2,INITRD_START+4-PARMAREA(%r12)# no ramdisk found, null it | ||
| 331 | .Lrdcont: | ||
| 332 | l %r2,INITRD_START+4-PARMAREA(%r12) | ||
| 333 | clc 0(3,%r2),.L_hdr # skip HDRx and EOFx | ||
| 334 | bz .Lagain2 | ||
| 335 | clc 0(3,%r2),.L_eof | ||
| 336 | bz .Lagain2 | ||
| 337 | |||
| 338 | #ifdef CONFIG_IPL_VM | ||
| 339 | # | ||
| 340 | # reset files in VM reader | ||
| 341 | # | ||
| 342 | stidp __LC_CPUID # store cpuid | ||
| 343 | tm __LC_CPUID,0xff # running VM ? | ||
| 344 | bno .Lnoreset | ||
| 345 | la %r2,.Lreset | ||
| 346 | lhi %r3,26 | ||
| 347 | diag %r2,%r3,8 | ||
| 348 | la %r5,.Lirb | ||
| 349 | stsch 0(%r5) # check if irq is pending | ||
| 350 | tm 30(%r5),0x0f # by verifying if any of the | ||
| 351 | bnz .Lwaitforirq # activity or status control | ||
| 352 | tm 31(%r5),0xff # bits is set in the schib | ||
| 353 | bz .Lnoreset | ||
| 354 | .Lwaitforirq: | ||
| 355 | mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw | ||
| 356 | .Lwaitrdrirq: | ||
| 357 | lpsw .Lrdrwaitpsw | ||
| 358 | .Lrdrint: | ||
| 359 | c %r1,0xb8 # compare subchannel number | ||
| 360 | bne .Lwaitrdrirq | ||
| 361 | la %r5,.Lirb | ||
| 362 | tsch 0(%r5) | ||
| 363 | .Lnoreset: | ||
| 364 | b .Lnoload | ||
| 365 | |||
| 366 | .align 8 | ||
| 367 | .Lrdrnewpsw: | ||
| 368 | .long 0x00080000,0x80000000+.Lrdrint | ||
| 369 | .Lrdrwaitpsw: | ||
| 370 | .long 0x020a0000,0x80000000+.Lrdrint | ||
| 371 | #endif | ||
| 372 | |||
| 373 | # | ||
| 374 | # everything loaded, go for it | ||
| 375 | # | ||
| 376 | .Lnoload: | ||
| 377 | l %r1,.Lstartup | ||
| 378 | br %r1 | ||
| 379 | |||
| 380 | .Lstartup: .long startup | ||
| 381 | .Lcvtab:.long _ebcasc # ebcdic to ascii table | ||
| 382 | .Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40 | ||
| 383 | .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6 | ||
| 384 | .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold" | ||
| 385 | .L_eof: .long 0xc5d6c600 /* C'EOF' */ | ||
| 386 | .L_hdr: .long 0xc8c4d900 /* C'HDR' */ | ||
| 387 | #endif /* CONFIG_IPL */ | ||
| 388 | |||
| 389 | # | ||
| 390 | # SALIPL loader support. Based on a patch by Rob van der Heij. | ||
| 391 | # This entry point is called directly from the SALIPL loader and | ||
| 392 | # doesn't need a builtin ipl record. | ||
| 393 | # | ||
| 394 | .org 0x800 | ||
| 395 | .globl start | ||
| 396 | start: | ||
| 397 | stm %r0,%r15,0x07b0 # store registers | ||
| 398 | basr %r12,%r0 | ||
| 399 | .base: | ||
| 400 | l %r11,.parm | ||
| 401 | l %r8,.cmd # pointer to command buffer | ||
| 402 | |||
| 403 | ltr %r9,%r9 # do we have SALIPL parameters? | ||
| 404 | bp .sk8x8 | ||
| 405 | |||
| 406 | mvc 0(64,%r8),0x00b0 # copy saved registers | ||
| 407 | xc 64(240-64,%r8),0(%r8) # remainder of buffer | ||
| 408 | tr 0(64,%r8),.lowcase | ||
| 409 | b .gotr | ||
| 410 | .sk8x8: | ||
| 411 | mvc 0(240,%r8),0(%r9) # copy iplparms into buffer | ||
| 412 | .gotr: | ||
| 413 | l %r10,.tbl # EBCDIC to ASCII table | ||
| 414 | tr 0(240,%r8),0(%r10) | ||
| 415 | stidp __LC_CPUID # Are we running on VM maybe | ||
| 416 | cli __LC_CPUID,0xff | ||
| 417 | bnz .test | ||
| 418 | .long 0x83300060 # diag 3,0,x'0060' - storage size | ||
| 419 | b .done | ||
| 420 | .test: | ||
| 421 | mvc 0x68(8),.pgmnw # set up pgm check handler | ||
| 422 | l %r2,.fourmeg | ||
| 423 | lr %r3,%r2 | ||
| 424 | bctr %r3,%r0 # 4M-1 | ||
| 425 | .loop: iske %r0,%r3 | ||
| 426 | ar %r3,%r2 | ||
| 427 | .pgmx: | ||
| 428 | sr %r3,%r2 | ||
| 429 | la %r3,1(%r3) | ||
| 430 | .done: | ||
| 431 | l %r1,.memsize | ||
| 432 | st %r3,4(%r1) | ||
| 433 | slr %r0,%r0 | ||
| 434 | st %r0,INITRD_SIZE+4-PARMAREA(%r11) | ||
| 435 | st %r0,INITRD_START+4-PARMAREA(%r11) | ||
| 436 | j startup # continue with startup | ||
| 437 | .tbl: .long _ebcasc # translate table | ||
| 438 | .cmd: .long COMMAND_LINE # address of command line buffer | ||
| 439 | .parm: .long PARMAREA | ||
| 440 | .fourmeg: .long 0x00400000 # 4M | ||
| 441 | .pgmnw: .long 0x00080000,.pgmx | ||
| 442 | .memsize: .long memory_size | ||
| 443 | .lowcase: | ||
| 444 | .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 | ||
| 445 | .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f | ||
| 446 | .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 | ||
| 447 | .byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f | ||
| 448 | .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 | ||
| 449 | .byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f | ||
| 450 | .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 | ||
| 451 | .byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f | ||
| 452 | .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47 | ||
| 453 | .byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f | ||
| 454 | .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57 | ||
| 455 | .byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f | ||
| 456 | .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67 | ||
| 457 | .byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f | ||
| 458 | .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77 | ||
| 459 | .byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f | ||
| 460 | |||
| 461 | .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87 | ||
| 462 | .byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f | ||
| 463 | .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97 | ||
| 464 | .byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f | ||
| 465 | .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 | ||
| 466 | .byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf | ||
| 467 | .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7 | ||
| 468 | .byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf | ||
| 469 | .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87 # .abcdefg | ||
| 470 | .byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf # hi | ||
| 471 | .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 # .jklmnop | ||
| 472 | .byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf # qr | ||
| 473 | .byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 # ..stuvwx | ||
| 474 | .byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef # yz | ||
| 475 | .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 | ||
| 476 | .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff | ||
| 477 | |||
| 478 | # | ||
| 479 | # startup-code at 0x10000, running in real mode | ||
| 480 | # this is called either by the ipl loader or directly by PSW restart | 15 | # this is called either by the ipl loader or directly by PSW restart | 
| 481 | # or linload or SALIPL | 16 | # or linload or SALIPL | 
| 482 | # | 17 | # | 
| @@ -530,7 +65,7 @@ startup:basr %r13,0 # get base | |||
| 530 | be .Lfchunk-.LPG1(%r13) # leave | 65 | be .Lfchunk-.LPG1(%r13) # leave | 
| 531 | chi %r1,2 | 66 | chi %r1,2 | 
| 532 | be .Lservicecall-.LPG1(%r13) | 67 | be .Lservicecall-.LPG1(%r13) | 
| 533 | lpsw .Lwaitsclp-.LPG1(%r13) | 68 | lpswe .Lwaitsclp-.LPG1(%r13) | 
| 534 | .Lsclph: | 69 | .Lsclph: | 
| 535 | lh %r1,.Lsccbr-PARMAREA(%r4) | 70 | lh %r1,.Lsccbr-PARMAREA(%r4) | 
| 536 | chi %r1,0x10 # 0x0010 is the sucess code | 71 | chi %r1,0x10 # 0x0010 is the sucess code | 
| @@ -567,8 +102,7 @@ startup:basr %r13,0 # get base | |||
| 567 | .Lcr: | 102 | .Lcr: | 
| 568 | .quad 0x00 # place holder for cr0 | 103 | .quad 0x00 # place holder for cr0 | 
| 569 | .Lwaitsclp: | 104 | .Lwaitsclp: | 
| 570 | .long 0x020A0000 | 105 | .quad 0x0102000180000000,.Lsclph | 
| 571 | .quad .Lsclph | ||
| 572 | .Lrcp: | 106 | .Lrcp: | 
| 573 | .int 0x00120001 # Read SCP forced code | 107 | .int 0x00120001 # Read SCP forced code | 
| 574 | .Lrcp2: | 108 | .Lrcp2: | 
| @@ -751,62 +285,7 @@ _pstart: | |||
| 751 | .global _pend | 285 | .global _pend | 
| 752 | _pend: | 286 | _pend: | 
| 753 | 287 | ||
| 754 | .Lget_ipl_device: | 288 | GET_IPL_DEVICE | 
| 755 | basr %r12,0 | ||
| 756 | .LPG2: l %r1,0xb8 # get sid | ||
| 757 | sll %r1,15 # test if subchannel is enabled | ||
| 758 | srl %r1,31 | ||
| 759 | ltr %r1,%r1 | ||
| 760 | bz 0(%r14) # subchannel disabled | ||
| 761 | l %r1,0xb8 | ||
| 762 | la %r5,.Lipl_schib-.LPG2(%r12) | ||
| 763 | stsch 0(%r5) # get schib of subchannel | ||
| 764 | bnz 0(%r14) # schib not available | ||
| 765 | tm 5(%r5),0x01 # devno valid? | ||
| 766 | bno 0(%r14) | ||
| 767 | la %r6,ipl_parameter_flags-.LPG2(%r12) | ||
| 768 | oi 3(%r6),0x01 # set flag | ||
| 769 | la %r2,ipl_devno-.LPG2(%r12) | ||
| 770 | mvc 0(2,%r2),6(%r5) # store devno | ||
| 771 | tm 4(%r5),0x80 # qdio capable device? | ||
| 772 | bno 0(%r14) | ||
| 773 | oi 3(%r6),0x02 # set flag | ||
| 774 | |||
| 775 | # copy ipl parameters | ||
| 776 | |||
| 777 | lhi %r0,4096 | ||
| 778 | l %r2,20(%r0) # get address of parameter list | ||
| 779 | lhi %r3,IPL_PARMBLOCK_ORIGIN | ||
| 780 | st %r3,20(%r0) | ||
| 781 | lhi %r4,1 | ||
| 782 | cr %r2,%r3 # start parameters < destination ? | ||
| 783 | jl 0f | ||
| 784 | lhi %r1,1 # copy direction is upwards | ||
| 785 | j 1f | ||
| 786 | 0: lhi %r1,-1 # copy direction is downwards | ||
| 787 | ar %r2,%r0 | ||
| 788 | ar %r3,%r0 | ||
| 789 | ar %r2,%r1 | ||
| 790 | ar %r3,%r1 | ||
| 791 | 1: mvc 0(1,%r3),0(%r2) # finally copy ipl parameters | ||
| 792 | ar %r3,%r1 | ||
| 793 | ar %r2,%r1 | ||
| 794 | sr %r0,%r4 | ||
| 795 | jne 1b | ||
| 796 | b 0(%r14) | ||
| 797 | |||
| 798 | .align 4 | ||
| 799 | .Lipl_schib: | ||
| 800 | .rept 13 | ||
| 801 | .long 0 | ||
| 802 | .endr | ||
| 803 | |||
| 804 | .globl ipl_parameter_flags | ||
| 805 | ipl_parameter_flags: | ||
| 806 | .long 0 | ||
| 807 | .globl ipl_devno | ||
| 808 | ipl_devno: | ||
| 809 | .word 0 | ||
| 810 | 289 | ||
| 811 | #ifdef CONFIG_SHARED_KERNEL | 290 | #ifdef CONFIG_SHARED_KERNEL | 
| 812 | .org 0x100000 | 291 | .org 0x100000 | 
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 9f3dff6c0b72..78b64fe5e7c2 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c  | |||
| @@ -99,15 +99,15 @@ void default_idle(void) | |||
| 99 | { | 99 | { | 
| 100 | int cpu, rc; | 100 | int cpu, rc; | 
| 101 | 101 | ||
| 102 | /* CPU is going idle. */ | ||
| 103 | cpu = smp_processor_id(); | ||
| 104 | |||
| 102 | local_irq_disable(); | 105 | local_irq_disable(); | 
| 103 | if (need_resched()) { | 106 | if (need_resched()) { | 
| 104 | local_irq_enable(); | 107 | local_irq_enable(); | 
| 105 | schedule(); | 108 | return; | 
| 106 | return; | 109 | } | 
| 107 | } | ||
| 108 | 110 | ||
| 109 | /* CPU is going idle. */ | ||
| 110 | cpu = smp_processor_id(); | ||
| 111 | rc = notifier_call_chain(&idle_chain, CPU_IDLE, (void *)(long) cpu); | 111 | rc = notifier_call_chain(&idle_chain, CPU_IDLE, (void *)(long) cpu); | 
| 112 | if (rc != NOTIFY_OK && rc != NOTIFY_DONE) | 112 | if (rc != NOTIFY_OK && rc != NOTIFY_DONE) | 
| 113 | BUG(); | 113 | BUG(); | 
| @@ -120,7 +120,7 @@ void default_idle(void) | |||
| 120 | __ctl_set_bit(8, 15); | 120 | __ctl_set_bit(8, 15); | 
| 121 | 121 | ||
| 122 | #ifdef CONFIG_HOTPLUG_CPU | 122 | #ifdef CONFIG_HOTPLUG_CPU | 
| 123 | if (cpu_is_offline(smp_processor_id())) | 123 | if (cpu_is_offline(cpu)) | 
| 124 | cpu_die(); | 124 | cpu_die(); | 
| 125 | #endif | 125 | #endif | 
| 126 | 126 | ||
| @@ -139,8 +139,14 @@ void default_idle(void) | |||
| 139 | 139 | ||
| 140 | void cpu_idle(void) | 140 | void cpu_idle(void) | 
| 141 | { | 141 | { | 
| 142 | for (;;) | 142 | for (;;) { | 
| 143 | default_idle(); | 143 | while (!need_resched()) | 
| 144 | default_idle(); | ||
| 145 | |||
| 146 | preempt_enable_no_resched(); | ||
| 147 | schedule(); | ||
| 148 | preempt_disable(); | ||
| 149 | } | ||
| 144 | } | 150 | } | 
| 145 | 151 | ||
| 146 | void show_regs(struct pt_regs *regs) | 152 | void show_regs(struct pt_regs *regs) | 
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index e13c87b446b2..5856b3fda6bf 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c  | |||
| @@ -533,6 +533,7 @@ int __devinit start_secondary(void *cpuvoid) | |||
| 533 | { | 533 | { | 
| 534 | /* Setup the cpu */ | 534 | /* Setup the cpu */ | 
| 535 | cpu_init(); | 535 | cpu_init(); | 
| 536 | preempt_disable(); | ||
| 536 | /* init per CPU timer */ | 537 | /* init per CPU timer */ | 
| 537 | init_cpu_timer(); | 538 | init_cpu_timer(); | 
| 538 | #ifdef CONFIG_VIRT_TIMER | 539 | #ifdef CONFIG_VIRT_TIMER | 
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 9a1d95894f3d..c36353e8c140 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c  | |||
| @@ -237,6 +237,8 @@ int sysctl_hz_timer = 1; | |||
| 237 | */ | 237 | */ | 
| 238 | static inline void stop_hz_timer(void) | 238 | static inline void stop_hz_timer(void) | 
| 239 | { | 239 | { | 
| 240 | unsigned long flags; | ||
| 241 | unsigned long seq, next; | ||
| 240 | __u64 timer, todval; | 242 | __u64 timer, todval; | 
| 241 | 243 | ||
| 242 | if (sysctl_hz_timer != 0) | 244 | if (sysctl_hz_timer != 0) | 
| @@ -257,7 +259,11 @@ static inline void stop_hz_timer(void) | |||
| 257 | * This cpu is going really idle. Set up the clock comparator | 259 | * This cpu is going really idle. Set up the clock comparator | 
| 258 | * for the next event. | 260 | * for the next event. | 
| 259 | */ | 261 | */ | 
| 260 | timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64; | 262 | next = next_timer_interrupt(); | 
| 263 | do { | ||
| 264 | seq = read_seqbegin_irqsave(&xtime_lock, flags); | ||
| 265 | timer = (__u64)(next - jiffies) + jiffies_64; | ||
| 266 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | ||
| 261 | todval = -1ULL; | 267 | todval = -1ULL; | 
| 262 | /* Be careful about overflows. */ | 268 | /* Be careful about overflows. */ | 
| 263 | if (timer < (-1ULL / CLK_TICKS_PER_JIFFY)) { | 269 | if (timer < (-1ULL / CLK_TICKS_PER_JIFFY)) { | 
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 6b8703ec2ae6..c5bd36fae56b 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c  | |||
| @@ -57,7 +57,6 @@ int sysctl_userprocess_debug = 0; | |||
| 57 | 57 | ||
| 58 | extern pgm_check_handler_t do_protection_exception; | 58 | extern pgm_check_handler_t do_protection_exception; | 
| 59 | extern pgm_check_handler_t do_dat_exception; | 59 | extern pgm_check_handler_t do_dat_exception; | 
| 60 | extern pgm_check_handler_t do_pseudo_page_fault; | ||
| 61 | #ifdef CONFIG_PFAULT | 60 | #ifdef CONFIG_PFAULT | 
| 62 | extern int pfault_init(void); | 61 | extern int pfault_init(void); | 
| 63 | extern void pfault_fini(void); | 62 | extern void pfault_fini(void); | 
| @@ -676,20 +675,6 @@ asmlinkage void kernel_stack_overflow(struct pt_regs * regs) | |||
| 676 | panic("Corrupt kernel stack, can't continue."); | 675 | panic("Corrupt kernel stack, can't continue."); | 
| 677 | } | 676 | } | 
| 678 | 677 | ||
| 679 | #ifndef CONFIG_ARCH_S390X | ||
| 680 | static int | ||
| 681 | pagex_reboot_event(struct notifier_block *this, unsigned long event, void *ptr) | ||
| 682 | { | ||
| 683 | if (MACHINE_IS_VM) | ||
| 684 | cpcmd("SET PAGEX OFF", NULL, 0, NULL); | ||
| 685 | return NOTIFY_DONE; | ||
| 686 | } | ||
| 687 | |||
| 688 | static struct notifier_block pagex_reboot_notifier = { | ||
| 689 | .notifier_call = &pagex_reboot_event, | ||
| 690 | }; | ||
| 691 | #endif | ||
| 692 | |||
| 693 | /* init is done in lowcore.S and head.S */ | 678 | /* init is done in lowcore.S and head.S */ | 
| 694 | 679 | ||
| 695 | void __init trap_init(void) | 680 | void __init trap_init(void) | 
| @@ -717,9 +702,7 @@ void __init trap_init(void) | |||
| 717 | pgm_check_table[0x11] = &do_dat_exception; | 702 | pgm_check_table[0x11] = &do_dat_exception; | 
| 718 | pgm_check_table[0x12] = &translation_exception; | 703 | pgm_check_table[0x12] = &translation_exception; | 
| 719 | pgm_check_table[0x13] = &special_op_exception; | 704 | pgm_check_table[0x13] = &special_op_exception; | 
| 720 | #ifndef CONFIG_ARCH_S390X | 705 | #ifdef CONFIG_ARCH_S390X | 
| 721 | pgm_check_table[0x14] = &do_pseudo_page_fault; | ||
| 722 | #else /* CONFIG_ARCH_S390X */ | ||
| 723 | pgm_check_table[0x38] = &do_dat_exception; | 706 | pgm_check_table[0x38] = &do_dat_exception; | 
| 724 | pgm_check_table[0x39] = &do_dat_exception; | 707 | pgm_check_table[0x39] = &do_dat_exception; | 
| 725 | pgm_check_table[0x3A] = &do_dat_exception; | 708 | pgm_check_table[0x3A] = &do_dat_exception; | 
| @@ -731,12 +714,10 @@ void __init trap_init(void) | |||
| 731 | pgm_check_table[0x40] = &do_monitor_call; | 714 | pgm_check_table[0x40] = &do_monitor_call; | 
| 732 | 715 | ||
| 733 | if (MACHINE_IS_VM) { | 716 | if (MACHINE_IS_VM) { | 
| 717 | #ifdef CONFIG_PFAULT | ||
| 734 | /* | 718 | /* | 
| 735 | * First try to get pfault pseudo page faults going. | 719 | * Try to get pfault pseudo page faults going. | 
| 736 | * If this isn't available turn on pagex page faults. | ||
| 737 | */ | 720 | */ | 
| 738 | #ifdef CONFIG_PFAULT | ||
| 739 | /* request the 0x2603 external interrupt */ | ||
| 740 | if (register_early_external_interrupt(0x2603, pfault_interrupt, | 721 | if (register_early_external_interrupt(0x2603, pfault_interrupt, | 
| 741 | &ext_int_pfault) != 0) | 722 | &ext_int_pfault) != 0) | 
| 742 | panic("Couldn't request external interrupt 0x2603"); | 723 | panic("Couldn't request external interrupt 0x2603"); | 
| @@ -748,9 +729,5 @@ void __init trap_init(void) | |||
| 748 | unregister_early_external_interrupt(0x2603, pfault_interrupt, | 729 | unregister_early_external_interrupt(0x2603, pfault_interrupt, | 
| 749 | &ext_int_pfault); | 730 | &ext_int_pfault); | 
| 750 | #endif | 731 | #endif | 
| 751 | #ifndef CONFIG_ARCH_S390X | ||
| 752 | register_reboot_notifier(&pagex_reboot_notifier); | ||
| 753 | cpcmd("SET PAGEX ON", NULL, 0, NULL); | ||
| 754 | #endif | ||
| 755 | } | 732 | } | 
| 756 | } | 733 | } | 
