summaryrefslogtreecommitdiff
path: root/arch/s390/kernel/als.c
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2016-06-27 15:52:38 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2016-07-31 05:27:58 -0400
commitbe2412c247c16c0ea4dd3293e8046e1b383c3bb6 (patch)
treec266913e26887b660c926aaad972914ca5b7c1f0 /arch/s390/kernel/als.c
parentcf9fdfea5f01bfebeeb28b4b27dc5151c7ea29d3 (diff)
s390/als: convert architecture level set code to C
There is no reason to have this code in assembly language. Therefore convert it to C. Note that this code needs special treatment: it is called very early and one of the side effects is that e.g. the bss section is not cleared. Therefore the preferred way for static variables is to put them on the stack which has a size of 16KB. There is no functional change with this patch. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Reviewed-by: Sascha Silbe <silbe@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/als.c')
-rw-r--r--arch/s390/kernel/als.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/arch/s390/kernel/als.c b/arch/s390/kernel/als.c
new file mode 100644
index 000000000000..f96a577972c4
--- /dev/null
+++ b/arch/s390/kernel/als.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright IBM Corp. 2016
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/processor.h>
+#include <asm/facility.h>
+#include <asm/lowcore.h>
+#include <asm/sclp.h>
+#include "entry.h"
+
+/*
+ * The code within this file will be called very early. It may _not_
+ * access anything within the bss section, since that is not cleared
+ * yet and may contain data (e.g. initrd) that must be saved by other
+ * code.
+ * For temporary objects the stack (16k) should be used.
+ */
+
+static unsigned long als[] __initdata = { FACILITIES_ALS };
+
+void __init verify_facilities(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(S390_lowcore.stfle_fac_list); i++)
+ S390_lowcore.stfle_fac_list[i] = 0;
+ asm volatile(
+ " stfl 0(0)\n"
+ : "=m" (S390_lowcore.stfl_fac_list));
+ S390_lowcore.stfle_fac_list[0] = (u64)S390_lowcore.stfl_fac_list << 32;
+ if (S390_lowcore.stfl_fac_list & 0x01000000) {
+ register unsigned long reg0 asm("0") = ARRAY_SIZE(als) - 1;
+
+ asm volatile(".insn s,0xb2b00000,0(%1)" /* stfle */
+ : "+d" (reg0)
+ : "a" (&S390_lowcore.stfle_fac_list)
+ : "memory", "cc");
+ }
+ for (i = 0; i < ARRAY_SIZE(als); i++) {
+ if ((S390_lowcore.stfle_fac_list[i] & als[i]) == als[i])
+ continue;
+ _sclp_print_early("The Linux kernel requires more recent processor hardware");
+ disabled_wait(0x8badcccc);
+ }
+}