aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/cio/cio.c38
1 files changed, 36 insertions, 2 deletions
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
912extern 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 */
922void 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}