diff options
Diffstat (limited to 'arch/s390/lib')
-rw-r--r-- | arch/s390/lib/Makefile | 10 | ||||
-rw-r--r-- | arch/s390/lib/delay.c | 37 | ||||
-rw-r--r-- | arch/s390/lib/strcmp.S | 4 | ||||
-rw-r--r-- | arch/s390/lib/strncpy.S | 6 | ||||
-rw-r--r-- | arch/s390/lib/uaccess.S | 51 |
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 + |