s390/als: convert architecture level set code to C
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Mon, 27 Jun 2016 13:52:38 +0000 (15:52 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Sun, 31 Jul 2016 09:27:58 +0000 (05:27 -0400)
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>
arch/s390/boot/compressed/Makefile
arch/s390/kernel/Makefile
arch/s390/kernel/als.c [new file with mode: 0644]
arch/s390/kernel/entry.h
arch/s390/kernel/head.S

index 98ec652cc332fc018b6026c2d89e19a30fbe3b67..13723c39e58e72ab0bf5900bedf5f78b8272c46a 100644 (file)
@@ -18,7 +18,7 @@ KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
 
 GCOV_PROFILE := n
 
-OBJECTS := $(addprefix $(objtree)/arch/s390/kernel/, head.o sclp.o ebcdic.o)
+OBJECTS := $(addprefix $(objtree)/arch/s390/kernel/, head.o sclp.o ebcdic.o als.o)
 OBJECTS += $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o
 
 LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup -T
index f37be37edd3a2ac56decfb387c3b662475e78354..07fca5e642b476f8997619b4ee93fbba83ba18d5 100644 (file)
@@ -4,6 +4,7 @@
 
 KCOV_INSTRUMENT_early.o := n
 KCOV_INSTRUMENT_sclp.o := n
+KCOV_INSTRUMENT_als.o := n
 
 ifdef CONFIG_FUNCTION_TRACER
 # Don't trace early setup code and tracing code
@@ -32,13 +33,16 @@ CFLAGS_ptrace.o             += -DUTS_MACHINE='"$(UTS_MACHINE)"'
 CFLAGS_sysinfo.o += -w
 
 #
-# Use -march=z900 for sclp.c to be able to print an error message if
-# the kernel is started on a machine which is too old
+# Use -march=z900 for sclp.c and als.c to be able to print an error
+# message if the kernel is started on a machine which is too old
 #
 CFLAGS_REMOVE_sclp.o = $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_als.o = $(CC_FLAGS_FTRACE)
 ifneq ($(CC_FLAGS_MARCH),-march=z900)
 CFLAGS_REMOVE_sclp.o   += $(CC_FLAGS_MARCH)
 CFLAGS_sclp.o          += -march=z900
+CFLAGS_REMOVE_als.o    += $(CC_FLAGS_MARCH)
+CFLAGS_als.o           += -march=z900
 AFLAGS_REMOVE_head.o   += $(CC_FLAGS_MARCH)
 AFLAGS_head.o          += -march=z900
 endif
@@ -46,7 +50,7 @@ GCOV_PROFILE_sclp.o := n
 
 obj-y  := traps.o time.o process.o base.o early.o setup.o idle.o vtime.o
 obj-y  += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o
-obj-y  += debug.o irq.o ipl.o dis.o diag.o sclp.o vdso.o
+obj-y  += debug.o irq.o ipl.o dis.o diag.o sclp.o vdso.o als.o
 obj-y  += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o
 obj-y  += runtime_instr.o cache.o fpu.o dumpstack.o
 obj-y  += entry.o reipl.o relocate_kernel.o
diff --git a/arch/s390/kernel/als.c b/arch/s390/kernel/als.c
new file mode 100644 (file)
index 0000000..f96a577
--- /dev/null
@@ -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);
+       }
+}
index bedd2f55d86088bd889c107c3e82b35d5d641f2b..e79f030dd276381bfeea25643077c607be951f1c 100644 (file)
@@ -79,4 +79,6 @@ long sys_s390_pci_mmio_read(unsigned long, void __user *, size_t);
 
 DECLARE_PER_CPU(u64, mt_cycles[8]);
 
+void verify_facilities(void);
+
 #endif /* _ENTRY_H */
index fcaefb041364c13f15ddd0c976846b683c626c5a..56e4d8234ef2ea1c2970ebcd6d8d5d2d15b5a037 100644 (file)
@@ -306,49 +306,14 @@ ENTRY(startup_kdump)
        stck    __LC_LAST_UPDATE_CLOCK
        spt     6f-.LPG0(%r13)
        mvc     __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
-       stfl    0(%r0)                  # store facilities @ __LC_STFL_FAC_LIST
-       mvc     __LC_STFLE_FAC_LIST(4),__LC_STFL_FAC_LIST
-       tm      __LC_STFLE_FAC_LIST,0x01        # stfle available ?
-       jz      0f
-       lghi    %r0,FACILITIES_ALS_DWORDS-1
-       .insn   s,0xb2b00000,__LC_STFLE_FAC_LIST # store facility list extended
-       # verify if all required facilities are supported by the machine
-0:     la      %r1,__LC_STFLE_FAC_LIST
-       la      %r2,3f+8-.LPG0(%r13)
-       lhi     %r3,FACILITIES_ALS_DWORDS
-1:     lg      %r0,0(%r1)
-       ng      %r0,0(%r2)
-       clg     %r0,0(%r2)
-       jne     2f
-       la      %r1,8(%r1)
-       la      %r2,8(%r2)
-       ahi     %r3,-1
-       jnz     1b
-       j       4f
-2:     l       %r15,.Lstack-.LPG0(%r13)
+       l       %r15,.Lstack-.LPG0(%r13)
        ahi     %r15,-STACK_FRAME_OVERHEAD
-       la      %r2,.Lals_string-.LPG0(%r13)
-       l       %r3,.Lsclp_print-.LPG0(%r13)
-       basr    %r14,%r3
-       lpsw    3f-.LPG0(%r13)          # machine type not good enough, crash
-.Lals_string:
-       .asciz  "The Linux kernel requires more recent processor hardware"
-.Lsclp_print:
-       .long   _sclp_print_early
-.Lstack:
-       .long   0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
-       .align 16
-3:     .long   0x000a0000,0x8badcccc
-
-# List of facilities that are required. If not all facilities are present
-# the kernel will crash.
-
-       .quad FACILITIES_ALS
-
-4:
+       brasl   %r14,verify_facilities
        /* Continue with startup code in head64.S */
        jg      startup_continue
 
+.Lstack:
+       .long   0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
        .align  8
 6:     .long   0x7fffffff,0xffffffff