diff options
Diffstat (limited to 'arch/s390/lib')
-rw-r--r-- | arch/s390/lib/Makefile | 12 | ||||
-rw-r--r-- | arch/s390/lib/checksum.c | 56 | ||||
-rw-r--r-- | arch/s390/lib/delay.c | 45 | ||||
-rw-r--r-- | arch/s390/lib/memset.S | 30 | ||||
-rw-r--r-- | arch/s390/lib/strcmp.S | 27 | ||||
-rw-r--r-- | arch/s390/lib/strncpy.S | 30 |
6 files changed, 200 insertions, 0 deletions
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile new file mode 100644 index 000000000..aa8b0e5da --- /dev/null +++ b/arch/s390/lib/Makefile @@ -0,0 +1,12 @@ +# +# Makefile for s390-specific library files.. +# + +.S.o: + $(CC) $(AFLAGS) -traditional -c $< -o $*.o + +L_TARGET = lib.a +L_OBJS = checksum.o delay.o memset.o strcmp.o strncpy.o + +include $(TOPDIR)/Rules.make + diff --git a/arch/s390/lib/checksum.c b/arch/s390/lib/checksum.c new file mode 100644 index 000000000..9411e1c5e --- /dev/null +++ b/arch/s390/lib/checksum.c @@ -0,0 +1,56 @@ +/* + * arch/s390/lib/checksum.c + * S390 fast network checksum routines + * + * S390 version + * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): Ulrich Hild (first version), + * Martin Schwidefsky (schwidefsky@de.ibm.com), + * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), + * + * This file contains network checksum routines + */ + +#include <linux/string.h> +#include <linux/types.h> +#include <asm/uaccess.h> +#include <asm/byteorder.h> +#include <asm/checksum.h> + +/* + * computes a partial checksum, e.g. for TCP/UDP fragments + */ +unsigned int +csum_partial (const unsigned char *buff, int len, unsigned int sum) +{ + /* + * Experiments with ethernet and slip connections show that buff + * is aligned on either a 2-byte or 4-byte boundary. + */ + __asm__ __volatile__ ( + " lr 2,%1\n" /* address in gpr 2 */ + " lr 3,%2\n" /* length in gpr 3 */ + "0: cksm %0,2\n" /* do checksum on longs */ + " jo 0b\n" + : "+&d" (sum) + : "d" (buff), "d" (len) + : "cc", "2", "3" ); + return sum; +} + +/* + * Fold a partial checksum without adding pseudo headers + */ +unsigned short csum_fold(unsigned int sum) +{ + __asm__ __volatile__ ( + " sr 3,3\n" /* %0 = H*65536 + L */ + " lr 2,%0\n" /* %0 = H L, R2/R3 = H L / 0 0 */ + " srdl 2,16\n" /* %0 = H L, R2/R3 = 0 H / L 0 */ + " alr 2,3\n" /* %0 = H L, R2/R3 = L H / L 0 */ + " alr %0,2\n" /* %0 = H+L+C L+H */ + " srl %0,16\n" /* %0 = H+L+C */ + : "+d" (sum) : : "cc", "2", "3"); + return ((unsigned short) ~sum); +} + diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c new file mode 100644 index 000000000..ec3274487 --- /dev/null +++ b/arch/s390/lib/delay.c @@ -0,0 +1,45 @@ +/* + * arch/s390/kernel/delay.c + * Precise Delay Loops for S390 + * + * S390 version + * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), + * + * Derived from "arch/i386/lib/delay.c" + * Copyright (C) 1993 Linus Torvalds + * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> + */ + +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/delay.h> + +#ifdef CONFIG_SMP +#include <asm/smp.h> +#endif + +void __delay(unsigned long loops) +{ + __asm__ __volatile__( + "0: ahi %0,-1\n" + " jnm 0b" + : /* no outputs */ : "r" (loops) ); +} + +inline void __const_udelay(unsigned long xloops) +{ + + __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); +} + +void __udelay(unsigned long usecs) +{ + __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ +} diff --git a/arch/s390/lib/memset.S b/arch/s390/lib/memset.S new file mode 100644 index 000000000..447af53f8 --- /dev/null +++ b/arch/s390/lib/memset.S @@ -0,0 +1,30 @@ +/* + * arch/s390/lib/memset.S + * S390 fast memset routine + * + * S390 version + * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), + */ + +/* + * R2 = address to memory area + * R3 = byte to fill memory with + * R4 = number of bytes to fill + */ + .globl memset +memset: + LTR 4,4 + JZ memset_end + LR 0,2 # save pointer to memory area + LR 1,3 # move pad byte to R1 + LR 3,4 + SR 4,4 # no source for MVCLE, only a pad byte + SR 5,5 + MVCLE 2,4,0(1) # thats it, MVCLE is your friend + JO .-4 + LR 2,0 # return pointer to mem. +memset_end: + BR 14 + + diff --git a/arch/s390/lib/strcmp.S b/arch/s390/lib/strcmp.S new file mode 100644 index 000000000..d3f63942f --- /dev/null +++ b/arch/s390/lib/strcmp.S @@ -0,0 +1,27 @@ +/* + * arch/s390/lib/strcmp.S + * S390 strcmp routine + * + * S390 version + * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), + */ + +/* + * R2 = address of compare string + * R3 = address of test string + */ + .globl strcmp +strcmp: + SR 0,0 + SR 1,1 + CLST 2,3 + JO .-4 + JE strcmp_equal + IC 0,0(0,3) + IC 1,0(0,2) + SR 1,0 +strcmp_equal: + LR 2,1 + BR 14 + diff --git a/arch/s390/lib/strncpy.S b/arch/s390/lib/strncpy.S new file mode 100644 index 000000000..83578909c --- /dev/null +++ b/arch/s390/lib/strncpy.S @@ -0,0 +1,30 @@ +/* + * arch/s390/kernel/strncpy.S + * S390 strncpy routine + * + * S390 version + * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), + */ + +/* + * R2 = address of destination + * R3 = address of source string + * R4 = max number of bytes to copy + */ + .globl strncpy +strncpy: + LR 1,2 # don't touch address in R2 + LTR 4,4 + JZ strncpy_exit # 0 bytes -> nothing to do + 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) + JZ strncpy_exit # ICM inserted a 0x00 + BRCT 4,strncpy_loop # R4 -= 1, jump to strncpy_loop if > 0 +strncpy_exit: + BR 14 + |