Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+648
+47
arch/unicore32/include/asm/uaccess.h
··· 1 + /* 2 + * linux/arch/unicore32/include/asm/uaccess.h 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + #ifndef __UNICORE_UACCESS_H__ 13 + #define __UNICORE_UACCESS_H__ 14 + 15 + #include <linux/thread_info.h> 16 + #include <linux/errno.h> 17 + 18 + #include <asm/memory.h> 19 + #include <asm/system.h> 20 + 21 + #define __copy_from_user __copy_from_user 22 + #define __copy_to_user __copy_to_user 23 + #define __strncpy_from_user __strncpy_from_user 24 + #define __strnlen_user __strnlen_user 25 + #define __clear_user __clear_user 26 + 27 + #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) 28 + #define __user_ok(addr, size) (((size) <= TASK_SIZE) \ 29 + && ((addr) <= TASK_SIZE - (size))) 30 + #define __access_ok(addr, size) (__kernel_ok || __user_ok((addr), (size))) 31 + 32 + extern unsigned long __must_check 33 + __copy_from_user(void *to, const void __user *from, unsigned long n); 34 + extern unsigned long __must_check 35 + __copy_to_user(void __user *to, const void *from, unsigned long n); 36 + extern unsigned long __must_check 37 + __clear_user(void __user *addr, unsigned long n); 38 + extern unsigned long __must_check 39 + __strncpy_from_user(char *to, const char __user *from, unsigned long count); 40 + extern unsigned long 41 + __strnlen_user(const char __user *s, long n); 42 + 43 + #include <asm-generic/uaccess.h> 44 + 45 + extern int fixup_exception(struct pt_regs *regs); 46 + 47 + #endif /* __UNICORE_UACCESS_H__ */
+57
arch/unicore32/lib/clear_user.S
··· 1 + /* 2 + * linux/arch/unicore32/lib/clear_user.S 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + #include <linux/linkage.h> 13 + #include <asm/assembler.h> 14 + 15 + .text 16 + 17 + /* Prototype: int __clear_user(void *addr, size_t sz) 18 + * Purpose : clear some user memory 19 + * Params : addr - user memory address to clear 20 + * : sz - number of bytes to clear 21 + * Returns : number of bytes NOT cleared 22 + */ 23 + WEAK(__clear_user) 24 + stm.w (lr), [sp-] 25 + stm.w (r1), [sp-] 26 + mov r2, #0 27 + csub.a r1, #4 28 + bsl 2f 29 + and.a ip, r0, #3 30 + beq 1f 31 + csub.a ip, #2 32 + strusr r2, r0, 1 33 + strusr r2, r0, 1, el 34 + strusr r2, r0, 1, sl 35 + rsub ip, ip, #4 36 + sub r1, r1, ip @ 7 6 5 4 3 2 1 37 + 1: sub.a r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7 38 + strusr r2, r0, 4, ns, rept=2 39 + bns 1b 40 + add.a r1, r1, #4 @ 3 2 1 0 -1 -2 -3 41 + strusr r2, r0, 4, ns 42 + 2: cand.a r1, #2 @ 1x 1x 0x 0x 1x 1x 0x 43 + strusr r2, r0, 1, ne, rept=2 44 + cand.a r1, #1 @ x1 x0 x1 x0 x1 x0 x1 45 + beq 3f 46 + USER( stb.u r2, [r0]) 47 + 3: mov r0, #0 48 + ldm.w (r1), [sp]+ 49 + ldm.w (pc), [sp]+ 50 + ENDPROC(__clear_user) 51 + 52 + .pushsection .fixup,"ax" 53 + .align 0 54 + 9001: ldm.w (r0), [sp]+ 55 + ldm.w (pc), [sp]+ 56 + .popsection 57 +
+108
arch/unicore32/lib/copy_from_user.S
··· 1 + /* 2 + * linux/arch/unicore32/lib/copy_from_user.S 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/linkage.h> 14 + #include <asm/assembler.h> 15 + 16 + /* 17 + * Prototype: 18 + * 19 + * size_t __copy_from_user(void *to, const void *from, size_t n) 20 + * 21 + * Purpose: 22 + * 23 + * copy a block to kernel memory from user memory 24 + * 25 + * Params: 26 + * 27 + * to = kernel memory 28 + * from = user memory 29 + * n = number of bytes to copy 30 + * 31 + * Return value: 32 + * 33 + * Number of bytes NOT copied. 34 + */ 35 + 36 + .macro ldr1w ptr reg abort 37 + ldrusr \reg, \ptr, 4, abort=\abort 38 + .endm 39 + 40 + .macro ldr4w ptr reg1 reg2 reg3 reg4 abort 41 + 100: ldm.w (\reg1, \reg2, \reg3, \reg4), [\ptr]+ 42 + .pushsection __ex_table, "a" 43 + .align 3 44 + .long 100b, \abort 45 + .popsection 46 + .endm 47 + 48 + .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort 49 + 100: ldm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+ 50 + .pushsection __ex_table, "a" 51 + .align 3 52 + .long 100b, \abort 53 + .popsection 54 + .endm 55 + 56 + .macro ldr1b ptr reg cond=al abort 57 + ldrusr \reg, \ptr, 1, \cond, abort=\abort 58 + .endm 59 + 60 + .macro str1w ptr reg abort 61 + stw.w \reg, [\ptr]+, #4 62 + .endm 63 + 64 + .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort 65 + stm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+ 66 + .endm 67 + 68 + .macro str1b ptr reg cond=al abort 69 + .ifnc \cond, al 70 + b\cond 201f 71 + b 202f 72 + .endif 73 + 201: stb.w \reg, [\ptr]+, #1 74 + 202: 75 + .endm 76 + 77 + .macro enter 78 + mov r3, #0 79 + stm.w (r0, r2, r3), [sp-] 80 + .endm 81 + 82 + .macro exit 83 + add sp, sp, #8 84 + ldm.w (r0), [sp]+ 85 + mov pc, lr 86 + .endm 87 + 88 + .text 89 + 90 + ENTRY(__copy_from_user) 91 + 92 + #include "copy_template.S" 93 + 94 + ENDPROC(__copy_from_user) 95 + 96 + .pushsection .fixup,"ax" 97 + .align 0 98 + copy_abort_preamble 99 + ldm.w (r1, r2), [sp]+ 100 + sub r3, r0, r1 101 + rsub r2, r3, r2 102 + stw r2, [sp] 103 + mov r1, #0 104 + b.l memset 105 + ldw.w r0, [sp]+, #4 106 + copy_abort_end 107 + .popsection 108 +
+39
arch/unicore32/lib/copy_page.S
··· 1 + /* 2 + * linux/arch/unicore32/lib/copy_page.S 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + * ASM optimised string functions 13 + */ 14 + #include <linux/linkage.h> 15 + #include <asm/assembler.h> 16 + #include <generated/asm-offsets.h> 17 + #include <asm/cache.h> 18 + 19 + #define COPY_COUNT (PAGE_SZ/256) 20 + 21 + .text 22 + .align 5 23 + /* 24 + * UniCore optimised copy_page routine 25 + */ 26 + ENTRY(copy_page) 27 + stm.w (r17 - r19, lr), [sp-] 28 + mov r17, r0 29 + mov r18, r1 30 + mov r19, #COPY_COUNT 31 + 1: 32 + .rept 4 33 + ldm.w (r0 - r15), [r18]+ 34 + stm.w (r0 - r15), [r17]+ 35 + .endr 36 + sub.a r19, r19, #1 37 + bne 1b 38 + ldm.w (r17 - r19, pc), [sp]+ 39 + ENDPROC(copy_page)
+214
arch/unicore32/lib/copy_template.S
··· 1 + /* 2 + * linux/arch/unicore32/lib/copy_template.S 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + /* 14 + * Theory of operation 15 + * ------------------- 16 + * 17 + * This file provides the core code for a forward memory copy used in 18 + * the implementation of memcopy(), copy_to_user() and copy_from_user(). 19 + * 20 + * The including file must define the following accessor macros 21 + * according to the need of the given function: 22 + * 23 + * ldr1w ptr reg abort 24 + * 25 + * This loads one word from 'ptr', stores it in 'reg' and increments 26 + * 'ptr' to the next word. The 'abort' argument is used for fixup tables. 27 + * 28 + * ldr4w ptr reg1 reg2 reg3 reg4 abort 29 + * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort 30 + * 31 + * This loads four or eight words starting from 'ptr', stores them 32 + * in provided registers and increments 'ptr' past those words. 33 + * The'abort' argument is used for fixup tables. 34 + * 35 + * ldr1b ptr reg cond abort 36 + * 37 + * Similar to ldr1w, but it loads a byte and increments 'ptr' one byte. 38 + * It also must apply the condition code if provided, otherwise the 39 + * "al" condition is assumed by default. 40 + * 41 + * str1w ptr reg abort 42 + * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort 43 + * str1b ptr reg cond abort 44 + * 45 + * Same as their ldr* counterparts, but data is stored to 'ptr' location 46 + * rather than being loaded. 47 + * 48 + * enter 49 + * 50 + * Preserve the provided registers on the stack plus any additional 51 + * data as needed by the implementation including this code. Called 52 + * upon code entry. 53 + * 54 + * exit 55 + * 56 + * Restore registers with the values previously saved with the 57 + * 'preserv' macro. Called upon code termination. 58 + */ 59 + 60 + 61 + enter 62 + 63 + sub.a r2, r2, #4 64 + bsl 8f 65 + and.a ip, r0, #3 66 + bne 9f 67 + and.a ip, r1, #3 68 + bne 10f 69 + 70 + 1: sub.a r2, r2, #(28) 71 + stm.w (r5 - r8), [sp-] 72 + bsl 5f 73 + 74 + 3: 75 + 4: ldr8w r1, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f 76 + sub.a r2, r2, #32 77 + str8w r0, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f 78 + beg 3b 79 + 80 + 5: and.a ip, r2, #28 81 + rsub ip, ip, #32 82 + beq 7f 83 + add pc, pc, ip @ C is always clear here 84 + nop 85 + 86 + ldr1w r1, r3, abort=20f 87 + ldr1w r1, r4, abort=20f 88 + ldr1w r1, r5, abort=20f 89 + ldr1w r1, r6, abort=20f 90 + ldr1w r1, r7, abort=20f 91 + ldr1w r1, r8, abort=20f 92 + ldr1w r1, r11, abort=20f 93 + 94 + add pc, pc, ip 95 + nop 96 + 97 + str1w r0, r3, abort=20f 98 + str1w r0, r4, abort=20f 99 + str1w r0, r5, abort=20f 100 + str1w r0, r6, abort=20f 101 + str1w r0, r7, abort=20f 102 + str1w r0, r8, abort=20f 103 + str1w r0, r11, abort=20f 104 + 105 + 7: ldm.w (r5 - r8), [sp]+ 106 + 107 + 8: mov.a r2, r2 << #31 108 + ldr1b r1, r3, ne, abort=21f 109 + ldr1b r1, r4, ea, abort=21f 110 + ldr1b r1, r10, ea, abort=21f 111 + str1b r0, r3, ne, abort=21f 112 + str1b r0, r4, ea, abort=21f 113 + str1b r0, r10, ea, abort=21f 114 + 115 + exit 116 + 117 + 9: rsub ip, ip, #4 118 + csub.a ip, #2 119 + ldr1b r1, r3, sg, abort=21f 120 + ldr1b r1, r4, eg, abort=21f 121 + ldr1b r1, r11, abort=21f 122 + str1b r0, r3, sg, abort=21f 123 + str1b r0, r4, eg, abort=21f 124 + sub.a r2, r2, ip 125 + str1b r0, r11, abort=21f 126 + bsl 8b 127 + and.a ip, r1, #3 128 + beq 1b 129 + 130 + 10: andn r1, r1, #3 131 + csub.a ip, #2 132 + ldr1w r1, r11, abort=21f 133 + beq 17f 134 + bsg 18f 135 + 136 + 137 + .macro forward_copy_shift a b 138 + 139 + sub.a r2, r2, #28 140 + bsl 14f 141 + 142 + 11: stm.w (r5 - r9), [sp-] 143 + 144 + 12: 145 + ldr4w r1, r4, r5, r6, r7, abort=19f 146 + mov r3, r11 pull #\a 147 + sub.a r2, r2, #32 148 + ldr4w r1, r8, r9, r10, r11, abort=19f 149 + or r3, r3, r4 push #\b 150 + mov r4, r4 pull #\a 151 + or r4, r4, r5 push #\b 152 + mov r5, r5 pull #\a 153 + or r5, r5, r6 push #\b 154 + mov r6, r6 pull #\a 155 + or r6, r6, r7 push #\b 156 + mov r7, r7 pull #\a 157 + or r7, r7, r8 push #\b 158 + mov r8, r8 pull #\a 159 + or r8, r8, r9 push #\b 160 + mov r9, r9 pull #\a 161 + or r9, r9, r10 push #\b 162 + mov r10, r10 pull #\a 163 + or r10, r10, r11 push #\b 164 + str8w r0, r3, r4, r5, r6, r7, r8, r9, r10, , abort=19f 165 + beg 12b 166 + 167 + ldm.w (r5 - r9), [sp]+ 168 + 169 + 14: and.a ip, r2, #28 170 + beq 16f 171 + 172 + 15: mov r3, r11 pull #\a 173 + ldr1w r1, r11, abort=21f 174 + sub.a ip, ip, #4 175 + or r3, r3, r11 push #\b 176 + str1w r0, r3, abort=21f 177 + bsg 15b 178 + 179 + 16: sub r1, r1, #(\b / 8) 180 + b 8b 181 + 182 + .endm 183 + 184 + 185 + forward_copy_shift a=8 b=24 186 + 187 + 17: forward_copy_shift a=16 b=16 188 + 189 + 18: forward_copy_shift a=24 b=8 190 + 191 + 192 + /* 193 + * Abort preamble and completion macros. 194 + * If a fixup handler is required then those macros must surround it. 195 + * It is assumed that the fixup code will handle the private part of 196 + * the exit macro. 197 + */ 198 + 199 + .macro copy_abort_preamble 200 + 19: ldm.w (r5 - r9), [sp]+ 201 + b 21f 202 + 299: .word 0 @ store lr 203 + @ to avoid function call in fixup 204 + 20: ldm.w (r5 - r8), [sp]+ 205 + 21: 206 + adr r1, 299b 207 + stw lr, [r1] 208 + .endm 209 + 210 + .macro copy_abort_end 211 + adr lr, 299b 212 + ldw pc, [lr] 213 + .endm 214 +
+96
arch/unicore32/lib/copy_to_user.S
··· 1 + /* 2 + * linux/arch/unicore32/lib/copy_to_user.S 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/linkage.h> 14 + #include <asm/assembler.h> 15 + 16 + /* 17 + * Prototype: 18 + * 19 + * size_t __copy_to_user(void *to, const void *from, size_t n) 20 + * 21 + * Purpose: 22 + * 23 + * copy a block to user memory from kernel memory 24 + * 25 + * Params: 26 + * 27 + * to = user memory 28 + * from = kernel memory 29 + * n = number of bytes to copy 30 + * 31 + * Return value: 32 + * 33 + * Number of bytes NOT copied. 34 + */ 35 + 36 + .macro ldr1w ptr reg abort 37 + ldw.w \reg, [\ptr]+, #4 38 + .endm 39 + 40 + .macro ldr4w ptr reg1 reg2 reg3 reg4 abort 41 + ldm.w (\reg1, \reg2, \reg3, \reg4), [\ptr]+ 42 + .endm 43 + 44 + .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort 45 + ldm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+ 46 + .endm 47 + 48 + .macro ldr1b ptr reg cond=al abort 49 + notcond \cond, .+8 50 + ldb.w \reg, [\ptr]+, #1 51 + .endm 52 + 53 + .macro str1w ptr reg abort 54 + strusr \reg, \ptr, 4, abort=\abort 55 + .endm 56 + 57 + .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort 58 + 100: stm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+ 59 + 60 + .pushsection __ex_table, "a" 61 + .long 100b, \abort 62 + .popsection 63 + .endm 64 + 65 + .macro str1b ptr reg cond=al abort 66 + strusr \reg, \ptr, 1, \cond, abort=\abort 67 + .endm 68 + 69 + .macro enter 70 + mov r3, #0 71 + stm.w (r0, r2, r3), [sp-] 72 + .endm 73 + 74 + .macro exit 75 + add sp, sp, #8 76 + ldm.w (r0), [sp]+ 77 + mov pc, lr 78 + .endm 79 + 80 + .text 81 + 82 + WEAK(__copy_to_user) 83 + 84 + #include "copy_template.S" 85 + 86 + ENDPROC(__copy_to_user) 87 + 88 + .pushsection .fixup,"ax" 89 + .align 0 90 + copy_abort_preamble 91 + ldm.w (r1, r2, r3), [sp]+ 92 + sub r0, r0, r1 93 + rsub r0, r0, r2 94 + copy_abort_end 95 + .popsection 96 +
+45
arch/unicore32/lib/strncpy_from_user.S
··· 1 + /* 2 + * linux/arch/unicore32/lib/strncpy_from_user.S 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + #include <linux/linkage.h> 13 + #include <asm/assembler.h> 14 + #include <asm/errno.h> 15 + 16 + .text 17 + .align 5 18 + 19 + /* 20 + * Copy a string from user space to kernel space. 21 + * r0 = dst, r1 = src, r2 = byte length 22 + * returns the number of characters copied (strlen of copied string), 23 + * -EFAULT on exception, or "len" if we fill the whole buffer 24 + */ 25 + ENTRY(__strncpy_from_user) 26 + mov ip, r1 27 + 1: sub.a r2, r2, #1 28 + ldrusr r3, r1, 1, ns 29 + bfs 2f 30 + stb.w r3, [r0]+, #1 31 + cxor.a r3, #0 32 + bne 1b 33 + sub r1, r1, #1 @ take NUL character out of count 34 + 2: sub r0, r1, ip 35 + mov pc, lr 36 + ENDPROC(__strncpy_from_user) 37 + 38 + .pushsection .fixup,"ax" 39 + .align 0 40 + 9001: mov r3, #0 41 + stb r3, [r0+], #0 @ null terminate 42 + mov r0, #-EFAULT 43 + mov pc, lr 44 + .popsection 45 +
+42
arch/unicore32/lib/strnlen_user.S
··· 1 + /* 2 + * linux/arch/unicore32/lib/strnlen_user.S 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + #include <linux/linkage.h> 13 + #include <asm/assembler.h> 14 + #include <asm/errno.h> 15 + 16 + .text 17 + .align 5 18 + 19 + /* Prototype: unsigned long __strnlen_user(const char *str, long n) 20 + * Purpose : get length of a string in user memory 21 + * Params : str - address of string in user memory 22 + * Returns : length of string *including terminator* 23 + * or zero on exception, or n + 1 if too long 24 + */ 25 + ENTRY(__strnlen_user) 26 + mov r2, r0 27 + 1: 28 + ldrusr r3, r0, 1 29 + cxor.a r3, #0 30 + beq 2f 31 + sub.a r1, r1, #1 32 + bne 1b 33 + add r0, r0, #1 34 + 2: sub r0, r0, r2 35 + mov pc, lr 36 + ENDPROC(__strnlen_user) 37 + 38 + .pushsection .fixup,"ax" 39 + .align 0 40 + 9001: mov r0, #0 41 + mov pc, lr 42 + .popsection