patch-2.1.80 linux/arch/arm/lib/uaccess-armo.S

Next file: linux/arch/arm/lib/uaccess.S
Previous file: linux/arch/arm/lib/testm.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.79/linux/arch/arm/lib/uaccess-armo.S linux/arch/arm/lib/uaccess-armo.S
@@ -0,0 +1,230 @@
+/*
+ * arch/arm/lib/uaccess-armo.S
+ *
+ * Copyright (C) 1998 Russell King
+ *
+ * Note!  Some code fragments found in here have a special calling
+ * convention - they are not APCS compliant!
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+		.text
+
+#define USER(x...)					\
+9999:		x;					\
+		.section __ex_table,"a";		\
+		.align	3;				\
+		.long	9999b,9001f;			\
+		.previous
+
+		.globl	SYMBOL_NAME(uaccess_user)
+SYMBOL_NAME(uaccess_user):
+		.word	uaccess_user_put_byte
+		.word	uaccess_user_get_byte
+		.word	uaccess_user_put_half
+		.word	uaccess_user_get_half
+		.word	uaccess_user_put_word
+		.word	uaccess_user_get_word
+		.word	__arch_copy_from_user
+		.word	__arch_copy_to_user
+		.word	__arch_clear_user
+		.word	__arch_strncpy_from_user
+		.word	__arch_strlen_user
+
+
+@ In : r0 = x, r1 = addr, r2 = error
+@ Out: r2 = error
+uaccess_user_put_byte:
+		stmfd	sp!, {lr}
+USER(		strbt	r0, [r1])
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = x, r1 = addr, r2 = error
+@ Out: r2 = error
+uaccess_user_put_half:
+		stmfd	sp!, {lr}
+USER(		strbt	r0, [r1], #1)
+		mov	r0, r0, lsr #8
+USER(		strbt	r0, [r1])
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = x, r1 = addr, r2 = error
+@ Out: r2 = error
+uaccess_user_put_word:
+		stmfd	sp!, {lr}
+USER(		strt	r0, [r1])
+		ldmfd	sp!, {pc}^
+
+9001:		mov	r2, #-EFAULT
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = addr, r1 = error
+@ Out: r0 = x, r1 = error
+uaccess_user_get_byte:
+		stmfd	sp!, {lr}
+USER(		ldrbt	r0, [r0])
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = addr, r1 = error
+@ Out: r0 = x, r1 = error
+uaccess_user_get_half:
+		stmfd	sp!, {lr}
+USER(		ldrt	r0, [r0])
+		mov	r0, r0, lsl #16
+		mov	r0, r0, lsr #16
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = addr, r1 = error
+@ Out: r0 = x, r1 = error
+uaccess_user_get_word:
+		stmfd	sp!, {lr}
+USER(		ldrt	r0, [r0])
+		ldmfd	sp!, {pc}^
+
+9001:		mov	r1, #-EFAULT
+		ldmfd	sp!, {pc}^
+
+
+
+		.globl	SYMBOL_NAME(uaccess_kernel)
+SYMBOL_NAME(uaccess_kernel):
+		.word	uaccess_kernel_put_byte
+		.word	uaccess_kernel_get_byte
+		.word	uaccess_kernel_put_half
+		.word	uaccess_kernel_get_half
+		.word	uaccess_kernel_put_word
+		.word	uaccess_kernel_get_word
+		.word	uaccess_kernel_copy
+		.word	uaccess_kernel_copy
+		.word	uaccess_kernel_clear
+		.word	uaccess_kernel_strncpy_from
+		.word	uaccess_kernel_strlen
+
+@ In : r0 = x, r1 = addr, r2 = error
+@ Out: r2 = error
+uaccess_kernel_put_byte:
+		stmfd	sp!, {lr}
+		strb	r0, [r1]
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = x, r1 = addr, r2 = error
+@ Out: r2 = error
+uaccess_kernel_put_half:
+		stmfd	sp!, {lr}
+		strb	r0, [r1]
+		mov	r0, r0, lsr #8
+		strb	r0, [r1, #1]
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = x, r1 = addr, r2 = error
+@ Out: r2 = error
+uaccess_kernel_put_word:
+		stmfd	sp!, {lr}
+		str	r0, [r1]
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = addr, r1 = error
+@ Out: r0 = x, r1 = error
+uaccess_kernel_get_byte:
+		stmfd	sp!, {lr}
+		ldrb	r0, [r0]
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = addr, r1 = error
+@ Out: r0 = x, r1 = error
+uaccess_kernel_get_half:
+		stmfd	sp!, {lr}
+		ldr	r0, [r0]
+		mov	r0, r0, lsl #16
+		mov	r0, r0, lsr #16
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = addr, r1 = error
+@ Out: r0 = x, r1 = error
+uaccess_kernel_get_word:
+		stmfd	sp!, {lr}
+		ldr	r0, [r0]
+		ldmfd	sp!, {pc}^
+
+
+/* Prototype: int uaccess_kernel_copy(void *to, const char *from, size_t n)
+ * Purpose  : copy a block to kernel memory from kernel memory
+ * Params   : to   - kernel memory
+ *          : from - kernel memory
+ *          : n    - number of bytes to copy
+ * Returns  : Number of bytes NOT copied.
+ */
+uaccess_kernel_copy:
+		stmfd	sp!, {lr}
+		bl	SYMBOL_NAME(memcpy)
+		mov	r0, #0
+		ldmfd	sp!, {pc}^
+
+/* Prototype: int uaccess_kernel_clear(void *addr, size_t sz)
+ * Purpose  : clear some kernel memory
+ * Params   : addr - kernel memory address to clear
+ *          : sz   - number of bytes to clear
+ * Returns  : number of bytes NOT cleared
+ */
+uaccess_kernel_clear:
+		stmfd	sp!, {lr}
+		mov	r2, #0
+		cmp	r1, #4
+		blt	2f
+		ands	ip, r0, #3
+		beq	1f
+		cmp	ip, #1
+		strb	r2, [r0], #1
+		strleb	r2, [r0], #1
+		strltb	r2, [r0], #1
+		rsb	ip, ip, #4
+		sub	r1, r1, ip		@  7  6  5  4  3  2  1
+1:		subs	r1, r1, #8		@ -1 -2 -3 -4 -5 -6 -7
+		bmi	2f
+		str	r2, [r0], #4
+		str	r2, [r0], #4
+		b	1b
+2:		adds	r1, r1, #4		@  3  2  1  0 -1 -2 -3
+		strpl	r2, [r0], #4
+		tst	r1, #2			@ 1x 1x 0x 0x 1x 1x 0x
+		strneb	r2, [r0], #1
+		strneb	r2, [r0], #1
+		tst	r1, #1			@ x1 x0 x1 x0 x1 x0 x1
+		strneb	r2, [r0], #1
+		mov	r0, #0
+		ldmfd	sp!, {pc}^
+
+/* Prototype: size_t uaccess_kernel_strncpy_from(char *dst, char *src, size_t len)
+ * Purpose  : copy a string from kernel memory to kernel memory
+ * Params   : dst - kernel memory destination
+ *          : src - kernel memory source
+ *          : len - maximum length of string
+ * Returns  : number of characters copied
+ */
+uaccess_kernel_strncpy_from:
+		stmfd	sp!, {lr}
+		mov	ip, r2
+1:		subs	r2, r2, #1
+		bmi	2f
+		ldrb	r3, [r1], #1
+		strb	r3, [r0], #1
+		teq	r3, #0
+		bne	1b
+2:		subs	r0, ip, r2
+		ldmfd	sp!, {pc}^
+
+/* Prototype: int uaccess_kernel_strlen(char *str)
+ * Purpose  : get length of a string in kernel memory
+ * Params   : str - address of string in kernel memory
+ * Returns  : length of string *including terminator*, or zero on error
+ */
+uaccess_kernel_strlen:
+		stmfd	sp!, {lr}
+		mov	r2, r0
+1:		ldrb	r1, [r0], #1
+		teq	r1, #0
+		bne	1b
+		sub	r0, r0, r2
+		ldmfd	sp!, {pc}^
+

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov