Skip to content

Commit

Permalink
unicore32 additional architecture files: low-level lib: uaccess
Browse files Browse the repository at this point in the history
This patch implements low-level uaccess libraries.

Signed-off-by: Guan Xuetao <[email protected]>
Acked-by: Arnd Bergmann <[email protected]>
  • Loading branch information
gxt committed Mar 17, 2011
1 parent 28bab05 commit 77c93b2
Show file tree
Hide file tree
Showing 8 changed files with 648 additions and 0 deletions.
47 changes: 47 additions & 0 deletions arch/unicore32/include/asm/uaccess.h
Original file line number Diff line number Diff line change
@@ -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__ */
57 changes: 57 additions & 0 deletions arch/unicore32/lib/clear_user.S
Original file line number Diff line number Diff line change
@@ -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

108 changes: 108 additions & 0 deletions arch/unicore32/lib/copy_from_user.S
Original file line number Diff line number Diff line change
@@ -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

39 changes: 39 additions & 0 deletions arch/unicore32/lib/copy_page.S
Original file line number Diff line number Diff line change
@@ -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)
Loading

0 comments on commit 77c93b2

Please sign in to comment.