aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/ipl.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/ipl.c')
-rw-r--r--arch/s390/kernel/ipl.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index ec127826f221..77f4aff630fe 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -19,6 +19,7 @@
19#include <asm/cpcmd.h> 19#include <asm/cpcmd.h>
20#include <asm/cio.h> 20#include <asm/cio.h>
21#include <asm/ebcdic.h> 21#include <asm/ebcdic.h>
22#include <asm/reset.h>
22 23
23#define IPL_PARM_BLOCK_VERSION 0 24#define IPL_PARM_BLOCK_VERSION 0
24#define LOADPARM_LEN 8 25#define LOADPARM_LEN 8
@@ -1024,3 +1025,56 @@ static int __init s390_ipl_init(void)
1024} 1025}
1025 1026
1026__initcall(s390_ipl_init); 1027__initcall(s390_ipl_init);
1028
1029static LIST_HEAD(rcall);
1030static DEFINE_MUTEX(rcall_mutex);
1031
1032void register_reset_call(struct reset_call *reset)
1033{
1034 mutex_lock(&rcall_mutex);
1035 list_add(&reset->list, &rcall);
1036 mutex_unlock(&rcall_mutex);
1037}
1038EXPORT_SYMBOL_GPL(register_reset_call);
1039
1040void unregister_reset_call(struct reset_call *reset)
1041{
1042 mutex_lock(&rcall_mutex);
1043 list_del(&reset->list);
1044 mutex_unlock(&rcall_mutex);
1045}
1046EXPORT_SYMBOL_GPL(unregister_reset_call);
1047
1048static void do_reset_calls(void)
1049{
1050 struct reset_call *reset;
1051
1052 list_for_each_entry(reset, &rcall, list)
1053 reset->fn();
1054}
1055
1056extern void reset_mcck_handler(void);
1057
1058void s390_reset_system(void)
1059{
1060 struct _lowcore *lc;
1061
1062 /* Disable all interrupts/machine checks */
1063 __load_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK);
1064
1065 /* Stack for interrupt/machine check handler */
1066 lc = (struct _lowcore *)(unsigned long) store_prefix();
1067 lc->panic_stack = S390_lowcore.panic_stack;
1068
1069 /* Disable prefixing */
1070 set_prefix(0);
1071
1072 /* Disable lowcore protection */
1073 __ctl_clear_bit(0,28);
1074
1075 /* Set new machine check handler */
1076 S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_MCHECK;
1077 S390_lowcore.mcck_new_psw.addr =
1078 PSW_ADDR_AMODE | (unsigned long) &reset_mcck_handler;
1079 do_reset_calls();
1080}