summaryrefslogtreecommitdiffstats
path: root/arch/s390/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/lib')
-rw-r--r--arch/s390/lib/Makefile10
-rw-r--r--arch/s390/lib/delay.c37
-rw-r--r--arch/s390/lib/strcmp.S4
-rw-r--r--arch/s390/lib/strncpy.S6
-rw-r--r--arch/s390/lib/uaccess.S51
5 files changed, 85 insertions, 23 deletions
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index aa8b0e5da..40ae70e8c 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -2,11 +2,17 @@
# Makefile for s390-specific library files..
#
+ifdef SMP
.S.o:
- $(CC) $(AFLAGS) -traditional -c $< -o $*.o
+ $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o
+else
+.S.o:
+ $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
+endif
L_TARGET = lib.a
-L_OBJS = checksum.o delay.o memset.o strcmp.o strncpy.o
+
+obj-y = checksum.o delay.o memset.o strcmp.o strncpy.o uaccess.o
include $(TOPDIR)/Rules.make
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c
index ec3274487..012a95308 100644
--- a/arch/s390/lib/delay.c
+++ b/arch/s390/lib/delay.c
@@ -21,25 +21,30 @@
void __delay(unsigned long loops)
{
- __asm__ __volatile__(
- "0: ahi %0,-1\n"
- " jnm 0b"
- : /* no outputs */ : "r" (loops) );
+ /*
+ * To end the bloody studid and useless discussion about the
+ * BogoMips number I took the liberty to define the __delay
+ * function in a way that that resulting BogoMips number will
+ * yield the megahertz number of the cpu. The important function
+ * is udelay and that is done using the tod clock. -- martin.
+ */
+ __asm__ __volatile__(
+ "0: brct %0,0b"
+ : /* no outputs */ : "r" (loops/2) );
}
-inline void __const_udelay(unsigned long xloops)
+/*
+ * Waits for 'usecs' microseconds using the tod clock
+ */
+void __udelay(unsigned long usecs)
{
+ uint64_t start_cc, end_cc;
- __asm__("LR 3,%1\n\t"
- "MR 2,%2\n\t"
- "LR %0,2\n\t"
- : "=r" (xloops)
- : "r" (xloops) , "r" (loops_per_sec)
- : "2" , "3");
- __delay(xloops);
+ if (usecs == 0)
+ return;
+ asm volatile ("STCK %0" : "=m" (start_cc));
+ do {
+ asm volatile ("STCK %0" : "=m" (end_cc));
+ } while (((end_cc - start_cc)/4096) < usecs);
}
-void __udelay(unsigned long usecs)
-{
- __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */
-}
diff --git a/arch/s390/lib/strcmp.S b/arch/s390/lib/strcmp.S
index d3f63942f..340edffb5 100644
--- a/arch/s390/lib/strcmp.S
+++ b/arch/s390/lib/strcmp.S
@@ -18,8 +18,8 @@ strcmp:
CLST 2,3
JO .-4
JE strcmp_equal
- IC 0,0(0,3)
- IC 1,0(0,2)
+ IC 0,0(3)
+ IC 1,0(2)
SR 1,0
strcmp_equal:
LR 2,1
diff --git a/arch/s390/lib/strncpy.S b/arch/s390/lib/strncpy.S
index 83578909c..3065be2b4 100644
--- a/arch/s390/lib/strncpy.S
+++ b/arch/s390/lib/strncpy.S
@@ -20,9 +20,9 @@ strncpy:
SR 0,0
strncpy_loop:
ICM 0,1,0(3) # ICM sets the cc, IC does not
- LA 3,1(0,3)
- STC 0,0(0,1)
- LA 1,1(0,1)
+ LA 3,1(3)
+ STC 0,0(1)
+ LA 1,1(1)
JZ strncpy_exit # ICM inserted a 0x00
BRCT 4,strncpy_loop # R4 -= 1, jump to strncpy_loop if > 0
strncpy_exit:
diff --git a/arch/s390/lib/uaccess.S b/arch/s390/lib/uaccess.S
new file mode 100644
index 000000000..8044d156d
--- /dev/null
+++ b/arch/s390/lib/uaccess.S
@@ -0,0 +1,51 @@
+/*
+ * arch/s390/lib/uaccess.S
+ * fixup routines for copy_{from|to}_user functions.
+ *
+ * s390
+ * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Authors(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
+ *
+ * These functions have a non-standard call interface
+ */
+
+#include <asm/lowcore.h>
+
+ .text
+ .align 4
+ .globl __copy_from_user_fixup
+__copy_from_user_fixup:
+ l 1,__LC_PGM_OLD_PSW+4
+ sll 4,1
+ srl 4,1
+0: lhi 3,-4096
+ sll 3,1
+ srl 3,1
+ n 3,__LC_TRANS_EXC_ADDR
+ sr 3,4
+ bm 4(1)
+1: mvcle 2,4,0
+ b 4(1)
+ .section __ex_table,"a"
+ .long 1b,0b
+ .previous
+
+ .align 4
+ .text
+ .globl __copy_to_user_fixup
+__copy_to_user_fixup:
+ l 1,__LC_PGM_OLD_PSW+4
+ sll 4,1
+ srl 4,1
+0: lhi 5,-4096
+ sll 5,1
+ srl 5,1
+ n 5,__LC_TRANS_EXC_ADDR
+ sr 5,4
+ bm 4(1)
+1: mvcle 4,2,0
+ b 4(1)
+ .section __ex_table,"a"
+ .long 1b,0b
+ .previous
+