unicore32 additional architecture files: low-level lib: uaccess
This patch implements low-level uaccess libraries. Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn> Acked-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
parent
28bab059a2
commit
77c93b2f23
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/unicore32/include/asm/uaccess.h
|
||||||
|
*
|
||||||
|
* Code specific to PKUnity SoC and UniCore ISA
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#ifndef __UNICORE_UACCESS_H__
|
||||||
|
#define __UNICORE_UACCESS_H__
|
||||||
|
|
||||||
|
#include <linux/thread_info.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
|
|
||||||
|
#include <asm/memory.h>
|
||||||
|
#include <asm/system.h>
|
||||||
|
|
||||||
|
#define __copy_from_user __copy_from_user
|
||||||
|
#define __copy_to_user __copy_to_user
|
||||||
|
#define __strncpy_from_user __strncpy_from_user
|
||||||
|
#define __strnlen_user __strnlen_user
|
||||||
|
#define __clear_user __clear_user
|
||||||
|
|
||||||
|
#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
|
||||||
|
#define __user_ok(addr, size) (((size) <= TASK_SIZE) \
|
||||||
|
&& ((addr) <= TASK_SIZE - (size)))
|
||||||
|
#define __access_ok(addr, size) (__kernel_ok || __user_ok((addr), (size)))
|
||||||
|
|
||||||
|
extern unsigned long __must_check
|
||||||
|
__copy_from_user(void *to, const void __user *from, unsigned long n);
|
||||||
|
extern unsigned long __must_check
|
||||||
|
__copy_to_user(void __user *to, const void *from, unsigned long n);
|
||||||
|
extern unsigned long __must_check
|
||||||
|
__clear_user(void __user *addr, unsigned long n);
|
||||||
|
extern unsigned long __must_check
|
||||||
|
__strncpy_from_user(char *to, const char __user *from, unsigned long count);
|
||||||
|
extern unsigned long
|
||||||
|
__strnlen_user(const char __user *s, long n);
|
||||||
|
|
||||||
|
#include <asm-generic/uaccess.h>
|
||||||
|
|
||||||
|
extern int fixup_exception(struct pt_regs *regs);
|
||||||
|
|
||||||
|
#endif /* __UNICORE_UACCESS_H__ */
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/unicore32/lib/clear_user.S
|
||||||
|
*
|
||||||
|
* Code specific to PKUnity SoC and UniCore ISA
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
#include <asm/assembler.h>
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
/* Prototype: int __clear_user(void *addr, size_t sz)
|
||||||
|
* Purpose : clear some user memory
|
||||||
|
* Params : addr - user memory address to clear
|
||||||
|
* : sz - number of bytes to clear
|
||||||
|
* Returns : number of bytes NOT cleared
|
||||||
|
*/
|
||||||
|
WEAK(__clear_user)
|
||||||
|
stm.w (lr), [sp-]
|
||||||
|
stm.w (r1), [sp-]
|
||||||
|
mov r2, #0
|
||||||
|
csub.a r1, #4
|
||||||
|
bsl 2f
|
||||||
|
and.a ip, r0, #3
|
||||||
|
beq 1f
|
||||||
|
csub.a ip, #2
|
||||||
|
strusr r2, r0, 1
|
||||||
|
strusr r2, r0, 1, el
|
||||||
|
strusr r2, r0, 1, sl
|
||||||
|
rsub ip, ip, #4
|
||||||
|
sub r1, r1, ip @ 7 6 5 4 3 2 1
|
||||||
|
1: sub.a r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7
|
||||||
|
strusr r2, r0, 4, ns, rept=2
|
||||||
|
bns 1b
|
||||||
|
add.a r1, r1, #4 @ 3 2 1 0 -1 -2 -3
|
||||||
|
strusr r2, r0, 4, ns
|
||||||
|
2: cand.a r1, #2 @ 1x 1x 0x 0x 1x 1x 0x
|
||||||
|
strusr r2, r0, 1, ne, rept=2
|
||||||
|
cand.a r1, #1 @ x1 x0 x1 x0 x1 x0 x1
|
||||||
|
beq 3f
|
||||||
|
USER( stb.u r2, [r0])
|
||||||
|
3: mov r0, #0
|
||||||
|
ldm.w (r1), [sp]+
|
||||||
|
ldm.w (pc), [sp]+
|
||||||
|
ENDPROC(__clear_user)
|
||||||
|
|
||||||
|
.pushsection .fixup,"ax"
|
||||||
|
.align 0
|
||||||
|
9001: ldm.w (r0), [sp]+
|
||||||
|
ldm.w (pc), [sp]+
|
||||||
|
.popsection
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/unicore32/lib/copy_from_user.S
|
||||||
|
*
|
||||||
|
* Code specific to PKUnity SoC and UniCore ISA
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
#include <asm/assembler.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prototype:
|
||||||
|
*
|
||||||
|
* size_t __copy_from_user(void *to, const void *from, size_t n)
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* copy a block to kernel memory from user memory
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
*
|
||||||
|
* to = kernel memory
|
||||||
|
* from = user memory
|
||||||
|
* n = number of bytes to copy
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
*
|
||||||
|
* Number of bytes NOT copied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.macro ldr1w ptr reg abort
|
||||||
|
ldrusr \reg, \ptr, 4, abort=\abort
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro ldr4w ptr reg1 reg2 reg3 reg4 abort
|
||||||
|
100: ldm.w (\reg1, \reg2, \reg3, \reg4), [\ptr]+
|
||||||
|
.pushsection __ex_table, "a"
|
||||||
|
.align 3
|
||||||
|
.long 100b, \abort
|
||||||
|
.popsection
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
|
||||||
|
100: ldm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+
|
||||||
|
.pushsection __ex_table, "a"
|
||||||
|
.align 3
|
||||||
|
.long 100b, \abort
|
||||||
|
.popsection
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro ldr1b ptr reg cond=al abort
|
||||||
|
ldrusr \reg, \ptr, 1, \cond, abort=\abort
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro str1w ptr reg abort
|
||||||
|
stw.w \reg, [\ptr]+, #4
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
|
||||||
|
stm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro str1b ptr reg cond=al abort
|
||||||
|
.ifnc \cond, al
|
||||||
|
b\cond 201f
|
||||||
|
b 202f
|
||||||
|
.endif
|
||||||
|
201: stb.w \reg, [\ptr]+, #1
|
||||||
|
202:
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro enter
|
||||||
|
mov r3, #0
|
||||||
|
stm.w (r0, r2, r3), [sp-]
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro exit
|
||||||
|
add sp, sp, #8
|
||||||
|
ldm.w (r0), [sp]+
|
||||||
|
mov pc, lr
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
ENTRY(__copy_from_user)
|
||||||
|
|
||||||
|
#include "copy_template.S"
|
||||||
|
|
||||||
|
ENDPROC(__copy_from_user)
|
||||||
|
|
||||||
|
.pushsection .fixup,"ax"
|
||||||
|
.align 0
|
||||||
|
copy_abort_preamble
|
||||||
|
ldm.w (r1, r2), [sp]+
|
||||||
|
sub r3, r0, r1
|
||||||
|
rsub r2, r3, r2
|
||||||
|
stw r2, [sp]
|
||||||
|
mov r1, #0
|
||||||
|
b.l memset
|
||||||
|
ldw.w r0, [sp]+, #4
|
||||||
|
copy_abort_end
|
||||||
|
.popsection
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/unicore32/lib/copy_page.S
|
||||||
|
*
|
||||||
|
* Code specific to PKUnity SoC and UniCore ISA
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* ASM optimised string functions
|
||||||
|
*/
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
#include <asm/assembler.h>
|
||||||
|
#include <generated/asm-offsets.h>
|
||||||
|
#include <asm/cache.h>
|
||||||
|
|
||||||
|
#define COPY_COUNT (PAGE_SZ/256)
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 5
|
||||||
|
/*
|
||||||
|
* UniCore optimised copy_page routine
|
||||||
|
*/
|
||||||
|
ENTRY(copy_page)
|
||||||
|
stm.w (r17 - r19, lr), [sp-]
|
||||||
|
mov r17, r0
|
||||||
|
mov r18, r1
|
||||||
|
mov r19, #COPY_COUNT
|
||||||
|
1:
|
||||||
|
.rept 4
|
||||||
|
ldm.w (r0 - r15), [r18]+
|
||||||
|
stm.w (r0 - r15), [r17]+
|
||||||
|
.endr
|
||||||
|
sub.a r19, r19, #1
|
||||||
|
bne 1b
|
||||||
|
ldm.w (r17 - r19, pc), [sp]+
|
||||||
|
ENDPROC(copy_page)
|
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/unicore32/lib/copy_template.S
|
||||||
|
*
|
||||||
|
* Code specific to PKUnity SoC and UniCore ISA
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Theory of operation
|
||||||
|
* -------------------
|
||||||
|
*
|
||||||
|
* This file provides the core code for a forward memory copy used in
|
||||||
|
* the implementation of memcopy(), copy_to_user() and copy_from_user().
|
||||||
|
*
|
||||||
|
* The including file must define the following accessor macros
|
||||||
|
* according to the need of the given function:
|
||||||
|
*
|
||||||
|
* ldr1w ptr reg abort
|
||||||
|
*
|
||||||
|
* This loads one word from 'ptr', stores it in 'reg' and increments
|
||||||
|
* 'ptr' to the next word. The 'abort' argument is used for fixup tables.
|
||||||
|
*
|
||||||
|
* ldr4w ptr reg1 reg2 reg3 reg4 abort
|
||||||
|
* ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
|
||||||
|
*
|
||||||
|
* This loads four or eight words starting from 'ptr', stores them
|
||||||
|
* in provided registers and increments 'ptr' past those words.
|
||||||
|
* The'abort' argument is used for fixup tables.
|
||||||
|
*
|
||||||
|
* ldr1b ptr reg cond abort
|
||||||
|
*
|
||||||
|
* Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
|
||||||
|
* It also must apply the condition code if provided, otherwise the
|
||||||
|
* "al" condition is assumed by default.
|
||||||
|
*
|
||||||
|
* str1w ptr reg abort
|
||||||
|
* str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
|
||||||
|
* str1b ptr reg cond abort
|
||||||
|
*
|
||||||
|
* Same as their ldr* counterparts, but data is stored to 'ptr' location
|
||||||
|
* rather than being loaded.
|
||||||
|
*
|
||||||
|
* enter
|
||||||
|
*
|
||||||
|
* Preserve the provided registers on the stack plus any additional
|
||||||
|
* data as needed by the implementation including this code. Called
|
||||||
|
* upon code entry.
|
||||||
|
*
|
||||||
|
* exit
|
||||||
|
*
|
||||||
|
* Restore registers with the values previously saved with the
|
||||||
|
* 'preserv' macro. Called upon code termination.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
enter
|
||||||
|
|
||||||
|
sub.a r2, r2, #4
|
||||||
|
bsl 8f
|
||||||
|
and.a ip, r0, #3
|
||||||
|
bne 9f
|
||||||
|
and.a ip, r1, #3
|
||||||
|
bne 10f
|
||||||
|
|
||||||
|
1: sub.a r2, r2, #(28)
|
||||||
|
stm.w (r5 - r8), [sp-]
|
||||||
|
bsl 5f
|
||||||
|
|
||||||
|
3:
|
||||||
|
4: ldr8w r1, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f
|
||||||
|
sub.a r2, r2, #32
|
||||||
|
str8w r0, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f
|
||||||
|
beg 3b
|
||||||
|
|
||||||
|
5: and.a ip, r2, #28
|
||||||
|
rsub ip, ip, #32
|
||||||
|
beq 7f
|
||||||
|
add pc, pc, ip @ C is always clear here
|
||||||
|
nop
|
||||||
|
|
||||||
|
ldr1w r1, r3, abort=20f
|
||||||
|
ldr1w r1, r4, abort=20f
|
||||||
|
ldr1w r1, r5, abort=20f
|
||||||
|
ldr1w r1, r6, abort=20f
|
||||||
|
ldr1w r1, r7, abort=20f
|
||||||
|
ldr1w r1, r8, abort=20f
|
||||||
|
ldr1w r1, r11, abort=20f
|
||||||
|
|
||||||
|
add pc, pc, ip
|
||||||
|
nop
|
||||||
|
|
||||||
|
str1w r0, r3, abort=20f
|
||||||
|
str1w r0, r4, abort=20f
|
||||||
|
str1w r0, r5, abort=20f
|
||||||
|
str1w r0, r6, abort=20f
|
||||||
|
str1w r0, r7, abort=20f
|
||||||
|
str1w r0, r8, abort=20f
|
||||||
|
str1w r0, r11, abort=20f
|
||||||
|
|
||||||
|
7: ldm.w (r5 - r8), [sp]+
|
||||||
|
|
||||||
|
8: mov.a r2, r2 << #31
|
||||||
|
ldr1b r1, r3, ne, abort=21f
|
||||||
|
ldr1b r1, r4, ea, abort=21f
|
||||||
|
ldr1b r1, r10, ea, abort=21f
|
||||||
|
str1b r0, r3, ne, abort=21f
|
||||||
|
str1b r0, r4, ea, abort=21f
|
||||||
|
str1b r0, r10, ea, abort=21f
|
||||||
|
|
||||||
|
exit
|
||||||
|
|
||||||
|
9: rsub ip, ip, #4
|
||||||
|
csub.a ip, #2
|
||||||
|
ldr1b r1, r3, sg, abort=21f
|
||||||
|
ldr1b r1, r4, eg, abort=21f
|
||||||
|
ldr1b r1, r11, abort=21f
|
||||||
|
str1b r0, r3, sg, abort=21f
|
||||||
|
str1b r0, r4, eg, abort=21f
|
||||||
|
sub.a r2, r2, ip
|
||||||
|
str1b r0, r11, abort=21f
|
||||||
|
bsl 8b
|
||||||
|
and.a ip, r1, #3
|
||||||
|
beq 1b
|
||||||
|
|
||||||
|
10: andn r1, r1, #3
|
||||||
|
csub.a ip, #2
|
||||||
|
ldr1w r1, r11, abort=21f
|
||||||
|
beq 17f
|
||||||
|
bsg 18f
|
||||||
|
|
||||||
|
|
||||||
|
.macro forward_copy_shift a b
|
||||||
|
|
||||||
|
sub.a r2, r2, #28
|
||||||
|
bsl 14f
|
||||||
|
|
||||||
|
11: stm.w (r5 - r9), [sp-]
|
||||||
|
|
||||||
|
12:
|
||||||
|
ldr4w r1, r4, r5, r6, r7, abort=19f
|
||||||
|
mov r3, r11 pull #\a
|
||||||
|
sub.a r2, r2, #32
|
||||||
|
ldr4w r1, r8, r9, r10, r11, abort=19f
|
||||||
|
or r3, r3, r4 push #\b
|
||||||
|
mov r4, r4 pull #\a
|
||||||
|
or r4, r4, r5 push #\b
|
||||||
|
mov r5, r5 pull #\a
|
||||||
|
or r5, r5, r6 push #\b
|
||||||
|
mov r6, r6 pull #\a
|
||||||
|
or r6, r6, r7 push #\b
|
||||||
|
mov r7, r7 pull #\a
|
||||||
|
or r7, r7, r8 push #\b
|
||||||
|
mov r8, r8 pull #\a
|
||||||
|
or r8, r8, r9 push #\b
|
||||||
|
mov r9, r9 pull #\a
|
||||||
|
or r9, r9, r10 push #\b
|
||||||
|
mov r10, r10 pull #\a
|
||||||
|
or r10, r10, r11 push #\b
|
||||||
|
str8w r0, r3, r4, r5, r6, r7, r8, r9, r10, , abort=19f
|
||||||
|
beg 12b
|
||||||
|
|
||||||
|
ldm.w (r5 - r9), [sp]+
|
||||||
|
|
||||||
|
14: and.a ip, r2, #28
|
||||||
|
beq 16f
|
||||||
|
|
||||||
|
15: mov r3, r11 pull #\a
|
||||||
|
ldr1w r1, r11, abort=21f
|
||||||
|
sub.a ip, ip, #4
|
||||||
|
or r3, r3, r11 push #\b
|
||||||
|
str1w r0, r3, abort=21f
|
||||||
|
bsg 15b
|
||||||
|
|
||||||
|
16: sub r1, r1, #(\b / 8)
|
||||||
|
b 8b
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
forward_copy_shift a=8 b=24
|
||||||
|
|
||||||
|
17: forward_copy_shift a=16 b=16
|
||||||
|
|
||||||
|
18: forward_copy_shift a=24 b=8
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Abort preamble and completion macros.
|
||||||
|
* If a fixup handler is required then those macros must surround it.
|
||||||
|
* It is assumed that the fixup code will handle the private part of
|
||||||
|
* the exit macro.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.macro copy_abort_preamble
|
||||||
|
19: ldm.w (r5 - r9), [sp]+
|
||||||
|
b 21f
|
||||||
|
299: .word 0 @ store lr
|
||||||
|
@ to avoid function call in fixup
|
||||||
|
20: ldm.w (r5 - r8), [sp]+
|
||||||
|
21:
|
||||||
|
adr r1, 299b
|
||||||
|
stw lr, [r1]
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro copy_abort_end
|
||||||
|
adr lr, 299b
|
||||||
|
ldw pc, [lr]
|
||||||
|
.endm
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/unicore32/lib/copy_to_user.S
|
||||||
|
*
|
||||||
|
* Code specific to PKUnity SoC and UniCore ISA
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
#include <asm/assembler.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prototype:
|
||||||
|
*
|
||||||
|
* size_t __copy_to_user(void *to, const void *from, size_t n)
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* copy a block to user memory from kernel memory
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
*
|
||||||
|
* to = user memory
|
||||||
|
* from = kernel memory
|
||||||
|
* n = number of bytes to copy
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
*
|
||||||
|
* Number of bytes NOT copied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.macro ldr1w ptr reg abort
|
||||||
|
ldw.w \reg, [\ptr]+, #4
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro ldr4w ptr reg1 reg2 reg3 reg4 abort
|
||||||
|
ldm.w (\reg1, \reg2, \reg3, \reg4), [\ptr]+
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
|
||||||
|
ldm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro ldr1b ptr reg cond=al abort
|
||||||
|
notcond \cond, .+8
|
||||||
|
ldb.w \reg, [\ptr]+, #1
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro str1w ptr reg abort
|
||||||
|
strusr \reg, \ptr, 4, abort=\abort
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
|
||||||
|
100: stm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+
|
||||||
|
|
||||||
|
.pushsection __ex_table, "a"
|
||||||
|
.long 100b, \abort
|
||||||
|
.popsection
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro str1b ptr reg cond=al abort
|
||||||
|
strusr \reg, \ptr, 1, \cond, abort=\abort
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro enter
|
||||||
|
mov r3, #0
|
||||||
|
stm.w (r0, r2, r3), [sp-]
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro exit
|
||||||
|
add sp, sp, #8
|
||||||
|
ldm.w (r0), [sp]+
|
||||||
|
mov pc, lr
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
WEAK(__copy_to_user)
|
||||||
|
|
||||||
|
#include "copy_template.S"
|
||||||
|
|
||||||
|
ENDPROC(__copy_to_user)
|
||||||
|
|
||||||
|
.pushsection .fixup,"ax"
|
||||||
|
.align 0
|
||||||
|
copy_abort_preamble
|
||||||
|
ldm.w (r1, r2, r3), [sp]+
|
||||||
|
sub r0, r0, r1
|
||||||
|
rsub r0, r0, r2
|
||||||
|
copy_abort_end
|
||||||
|
.popsection
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/unicore32/lib/strncpy_from_user.S
|
||||||
|
*
|
||||||
|
* Code specific to PKUnity SoC and UniCore ISA
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
#include <asm/assembler.h>
|
||||||
|
#include <asm/errno.h>
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 5
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy a string from user space to kernel space.
|
||||||
|
* r0 = dst, r1 = src, r2 = byte length
|
||||||
|
* returns the number of characters copied (strlen of copied string),
|
||||||
|
* -EFAULT on exception, or "len" if we fill the whole buffer
|
||||||
|
*/
|
||||||
|
ENTRY(__strncpy_from_user)
|
||||||
|
mov ip, r1
|
||||||
|
1: sub.a r2, r2, #1
|
||||||
|
ldrusr r3, r1, 1, ns
|
||||||
|
bfs 2f
|
||||||
|
stb.w r3, [r0]+, #1
|
||||||
|
cxor.a r3, #0
|
||||||
|
bne 1b
|
||||||
|
sub r1, r1, #1 @ take NUL character out of count
|
||||||
|
2: sub r0, r1, ip
|
||||||
|
mov pc, lr
|
||||||
|
ENDPROC(__strncpy_from_user)
|
||||||
|
|
||||||
|
.pushsection .fixup,"ax"
|
||||||
|
.align 0
|
||||||
|
9001: mov r3, #0
|
||||||
|
stb r3, [r0+], #0 @ null terminate
|
||||||
|
mov r0, #-EFAULT
|
||||||
|
mov pc, lr
|
||||||
|
.popsection
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/unicore32/lib/strnlen_user.S
|
||||||
|
*
|
||||||
|
* Code specific to PKUnity SoC and UniCore ISA
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
#include <asm/assembler.h>
|
||||||
|
#include <asm/errno.h>
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 5
|
||||||
|
|
||||||
|
/* Prototype: unsigned long __strnlen_user(const char *str, long n)
|
||||||
|
* Purpose : get length of a string in user memory
|
||||||
|
* Params : str - address of string in user memory
|
||||||
|
* Returns : length of string *including terminator*
|
||||||
|
* or zero on exception, or n + 1 if too long
|
||||||
|
*/
|
||||||
|
ENTRY(__strnlen_user)
|
||||||
|
mov r2, r0
|
||||||
|
1:
|
||||||
|
ldrusr r3, r0, 1
|
||||||
|
cxor.a r3, #0
|
||||||
|
beq 2f
|
||||||
|
sub.a r1, r1, #1
|
||||||
|
bne 1b
|
||||||
|
add r0, r0, #1
|
||||||
|
2: sub r0, r0, r2
|
||||||
|
mov pc, lr
|
||||||
|
ENDPROC(__strnlen_user)
|
||||||
|
|
||||||
|
.pushsection .fixup,"ax"
|
||||||
|
.align 0
|
||||||
|
9001: mov r0, #0
|
||||||
|
mov pc, lr
|
||||||
|
.popsection
|
Loading…
Reference in New Issue