Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9dc7356e authored by Michael Holzheu's avatar Michael Holzheu Committed by Heiko Carstens
Browse files

[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: default avatarMichael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
parent ef1daec8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -167,5 +167,6 @@ enum diag308_rc {
};

extern int diag308(unsigned long subcode, void *addr);
extern void diag308_reset(void);

#endif /* _ASM_S390_IPL_H */
+36 −0
Original line number Diff line number Diff line
@@ -76,6 +76,42 @@ s390_base_pgm_handler_fn:
	.quad	0
	.previous

#
# Calls diag 308 subcode 1 and continues execution
#
# The following conditions must be ensured before calling this function:
# * Prefix register = 0
# * Lowcore protection is disabled
#
ENTRY(diag308_reset)
	larl	%r4,.Lctlregs		# Save control registers
	stctg	%c0,%c15,0(%r4)
	larl	%r4,.Lrestart_psw	# Setup restart PSW at absolute 0
	lghi	%r3,0
	lg	%r4,0(%r4)		# Save PSW
	sturg	%r4,%r3			# Use sturg, because of large pages
	lghi	%r1,1
	diag	%r1,%r1,0x308
.Lrestart_part2:
	lhi	%r0,0			# Load r0 with zero
	lhi	%r1,2			# Use mode 2 = ESAME (dump)
	sigp	%r1,%r0,0x12		# Switch to ESAME mode
	sam64				# Switch to 64 bit addressing mode
	larl	%r4,.Lctlregs		# Restore control registers
	lctlg	%c0,%c15,0(%r4)
	br	%r14
.align 16
.Lrestart_psw:
	.long	0x00080000,0x80000000 + .Lrestart_part2

	.section .bss
.align 8
.Lctlregs:
	.rept	16
	.quad	0
	.endr
	.previous

#else /* CONFIG_64BIT */

ENTRY(s390_base_mcck_handler)
+6 −0
Original line number Diff line number Diff line
@@ -1996,6 +1996,12 @@ static void do_reset_calls(void)
{
	struct reset_call *reset;

#ifdef CONFIG_64BIT
	if (diag308_set_works) {
		diag308_reset();
		return;
	}
#endif
	list_for_each_entry(reset, &rcall, list)
		reset->fn();
}