diff options
author | Michael Holzheu <holzheu@linux.vnet.ibm.com> | 2011-08-03 10:44:22 -0400 |
---|---|---|
committer | Heiko Carstens <heiko.carstens@de.ibm.com> | 2011-08-03 10:44:19 -0400 |
commit | 9dc7356ee1266d6a69fc80f28d006f71c20bf172 (patch) | |
tree | f2b9c912d9859cd70e1f86b05d75bd78af922461 /arch/s390 | |
parent | ef1daec8da2c04b0c6e91a34b9cac1aad33c6692 (diff) |
[S390] Use diagnose 308 for system reset
The diagnose 308 call is the prefered method for clearing all ongoing I/O.
Therefore if it is available we use it instead of doing a manual reset.
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/include/asm/ipl.h | 1 | ||||
-rw-r--r-- | arch/s390/kernel/base.S | 36 | ||||
-rw-r--r-- | arch/s390/kernel/ipl.c | 6 |
3 files changed, 43 insertions, 0 deletions
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index 5e95d95450b3..97cc4403fabf 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h | |||
@@ -167,5 +167,6 @@ enum diag308_rc { | |||
167 | }; | 167 | }; |
168 | 168 | ||
169 | extern int diag308(unsigned long subcode, void *addr); | 169 | extern int diag308(unsigned long subcode, void *addr); |
170 | extern void diag308_reset(void); | ||
170 | 171 | ||
171 | #endif /* _ASM_S390_IPL_H */ | 172 | #endif /* _ASM_S390_IPL_H */ |
diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S index 209938c1dfc8..255435663bf8 100644 --- a/arch/s390/kernel/base.S +++ b/arch/s390/kernel/base.S | |||
@@ -76,6 +76,42 @@ s390_base_pgm_handler_fn: | |||
76 | .quad 0 | 76 | .quad 0 |
77 | .previous | 77 | .previous |
78 | 78 | ||
79 | # | ||
80 | # Calls diag 308 subcode 1 and continues execution | ||
81 | # | ||
82 | # The following conditions must be ensured before calling this function: | ||
83 | # * Prefix register = 0 | ||
84 | # * Lowcore protection is disabled | ||
85 | # | ||
86 | ENTRY(diag308_reset) | ||
87 | larl %r4,.Lctlregs # Save control registers | ||
88 | stctg %c0,%c15,0(%r4) | ||
89 | larl %r4,.Lrestart_psw # Setup restart PSW at absolute 0 | ||
90 | lghi %r3,0 | ||
91 | lg %r4,0(%r4) # Save PSW | ||
92 | sturg %r4,%r3 # Use sturg, because of large pages | ||
93 | lghi %r1,1 | ||
94 | diag %r1,%r1,0x308 | ||
95 | .Lrestart_part2: | ||
96 | lhi %r0,0 # Load r0 with zero | ||
97 | lhi %r1,2 # Use mode 2 = ESAME (dump) | ||
98 | sigp %r1,%r0,0x12 # Switch to ESAME mode | ||
99 | sam64 # Switch to 64 bit addressing mode | ||
100 | larl %r4,.Lctlregs # Restore control registers | ||
101 | lctlg %c0,%c15,0(%r4) | ||
102 | br %r14 | ||
103 | .align 16 | ||
104 | .Lrestart_psw: | ||
105 | .long 0x00080000,0x80000000 + .Lrestart_part2 | ||
106 | |||
107 | .section .bss | ||
108 | .align 8 | ||
109 | .Lctlregs: | ||
110 | .rept 16 | ||
111 | .quad 0 | ||
112 | .endr | ||
113 | .previous | ||
114 | |||
79 | #else /* CONFIG_64BIT */ | 115 | #else /* CONFIG_64BIT */ |
80 | 116 | ||
81 | ENTRY(s390_base_mcck_handler) | 117 | ENTRY(s390_base_mcck_handler) |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 059c59027ac0..04361d5a4279 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -1996,6 +1996,12 @@ static void do_reset_calls(void) | |||
1996 | { | 1996 | { |
1997 | struct reset_call *reset; | 1997 | struct reset_call *reset; |
1998 | 1998 | ||
1999 | #ifdef CONFIG_64BIT | ||
2000 | if (diag308_set_works) { | ||
2001 | diag308_reset(); | ||
2002 | return; | ||
2003 | } | ||
2004 | #endif | ||
1999 | list_for_each_entry(reset, &rcall, list) | 2005 | list_for_each_entry(reset, &rcall, list) |
2000 | reset->fn(); | 2006 | reset->fn(); |
2001 | } | 2007 | } |