···11+/*22+ * linux/arch/unicore32/include/asm/uaccess.h33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ */1212+#ifndef __UNICORE_UACCESS_H__1313+#define __UNICORE_UACCESS_H__1414+1515+#include <linux/thread_info.h>1616+#include <linux/errno.h>1717+1818+#include <asm/memory.h>1919+#include <asm/system.h>2020+2121+#define __copy_from_user __copy_from_user2222+#define __copy_to_user __copy_to_user2323+#define __strncpy_from_user __strncpy_from_user2424+#define __strnlen_user __strnlen_user2525+#define __clear_user __clear_user2626+2727+#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))2828+#define __user_ok(addr, size) (((size) <= TASK_SIZE) \2929+ && ((addr) <= TASK_SIZE - (size)))3030+#define __access_ok(addr, size) (__kernel_ok || __user_ok((addr), (size)))3131+3232+extern unsigned long __must_check3333+__copy_from_user(void *to, const void __user *from, unsigned long n);3434+extern unsigned long __must_check3535+__copy_to_user(void __user *to, const void *from, unsigned long n);3636+extern unsigned long __must_check3737+__clear_user(void __user *addr, unsigned long n);3838+extern unsigned long __must_check3939+__strncpy_from_user(char *to, const char __user *from, unsigned long count);4040+extern unsigned long4141+__strnlen_user(const char __user *s, long n);4242+4343+#include <asm-generic/uaccess.h>4444+4545+extern int fixup_exception(struct pt_regs *regs);4646+4747+#endif /* __UNICORE_UACCESS_H__ */
+57
arch/unicore32/lib/clear_user.S
···11+/*22+ * linux/arch/unicore32/lib/clear_user.S33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ */1212+#include <linux/linkage.h>1313+#include <asm/assembler.h>1414+1515+ .text1616+1717+/* Prototype: int __clear_user(void *addr, size_t sz)1818+ * Purpose : clear some user memory1919+ * Params : addr - user memory address to clear2020+ * : sz - number of bytes to clear2121+ * Returns : number of bytes NOT cleared2222+ */2323+WEAK(__clear_user)2424+ stm.w (lr), [sp-]2525+ stm.w (r1), [sp-]2626+ mov r2, #02727+ csub.a r1, #42828+ bsl 2f2929+ and.a ip, r0, #33030+ beq 1f3131+ csub.a ip, #23232+ strusr r2, r0, 13333+ strusr r2, r0, 1, el3434+ strusr r2, r0, 1, sl3535+ rsub ip, ip, #43636+ sub r1, r1, ip @ 7 6 5 4 3 2 13737+1: sub.a r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -73838+ strusr r2, r0, 4, ns, rept=23939+ bns 1b4040+ add.a r1, r1, #4 @ 3 2 1 0 -1 -2 -34141+ strusr r2, r0, 4, ns4242+2: cand.a r1, #2 @ 1x 1x 0x 0x 1x 1x 0x4343+ strusr r2, r0, 1, ne, rept=24444+ cand.a r1, #1 @ x1 x0 x1 x0 x1 x0 x14545+ beq 3f4646+USER( stb.u r2, [r0])4747+3: mov r0, #04848+ ldm.w (r1), [sp]+4949+ ldm.w (pc), [sp]+5050+ENDPROC(__clear_user)5151+5252+ .pushsection .fixup,"ax"5353+ .align 05454+9001: ldm.w (r0), [sp]+5555+ ldm.w (pc), [sp]+5656+ .popsection5757+
+108
arch/unicore32/lib/copy_from_user.S
···11+/*22+ * linux/arch/unicore32/lib/copy_from_user.S33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ */1212+1313+#include <linux/linkage.h>1414+#include <asm/assembler.h>1515+1616+/*1717+ * Prototype:1818+ *1919+ * size_t __copy_from_user(void *to, const void *from, size_t n)2020+ *2121+ * Purpose:2222+ *2323+ * copy a block to kernel memory from user memory2424+ *2525+ * Params:2626+ *2727+ * to = kernel memory2828+ * from = user memory2929+ * n = number of bytes to copy3030+ *3131+ * Return value:3232+ *3333+ * Number of bytes NOT copied.3434+ */3535+3636+ .macro ldr1w ptr reg abort3737+ ldrusr \reg, \ptr, 4, abort=\abort3838+ .endm3939+4040+ .macro ldr4w ptr reg1 reg2 reg3 reg4 abort4141+100: ldm.w (\reg1, \reg2, \reg3, \reg4), [\ptr]+4242+ .pushsection __ex_table, "a"4343+ .align 34444+ .long 100b, \abort4545+ .popsection4646+ .endm4747+4848+ .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort4949+100: ldm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+5050+ .pushsection __ex_table, "a"5151+ .align 35252+ .long 100b, \abort5353+ .popsection5454+ .endm5555+5656+ .macro ldr1b ptr reg cond=al abort5757+ ldrusr \reg, \ptr, 1, \cond, abort=\abort5858+ .endm5959+6060+ .macro str1w ptr reg abort6161+ stw.w \reg, [\ptr]+, #46262+ .endm6363+6464+ .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort6565+ stm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+6666+ .endm6767+6868+ .macro str1b ptr reg cond=al abort6969+ .ifnc \cond, al7070+ b\cond 201f7171+ b 202f7272+ .endif7373+201: stb.w \reg, [\ptr]+, #17474+202:7575+ .endm7676+7777+ .macro enter7878+ mov r3, #07979+ stm.w (r0, r2, r3), [sp-]8080+ .endm8181+8282+ .macro exit8383+ add sp, sp, #88484+ ldm.w (r0), [sp]+8585+ mov pc, lr8686+ .endm8787+8888+ .text8989+9090+ENTRY(__copy_from_user)9191+9292+#include "copy_template.S"9393+9494+ENDPROC(__copy_from_user)9595+9696+ .pushsection .fixup,"ax"9797+ .align 09898+ copy_abort_preamble9999+ ldm.w (r1, r2), [sp]+100100+ sub r3, r0, r1101101+ rsub r2, r3, r2102102+ stw r2, [sp]103103+ mov r1, #0104104+ b.l memset105105+ ldw.w r0, [sp]+, #4106106+ copy_abort_end107107+ .popsection108108+
+39
arch/unicore32/lib/copy_page.S
···11+/*22+ * linux/arch/unicore32/lib/copy_page.S33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ *1212+ * ASM optimised string functions1313+ */1414+#include <linux/linkage.h>1515+#include <asm/assembler.h>1616+#include <generated/asm-offsets.h>1717+#include <asm/cache.h>1818+1919+#define COPY_COUNT (PAGE_SZ/256)2020+2121+ .text2222+ .align 52323+/*2424+ * UniCore optimised copy_page routine2525+ */2626+ENTRY(copy_page)2727+ stm.w (r17 - r19, lr), [sp-]2828+ mov r17, r02929+ mov r18, r13030+ mov r19, #COPY_COUNT3131+1:3232+ .rept 43333+ ldm.w (r0 - r15), [r18]+3434+ stm.w (r0 - r15), [r17]+3535+ .endr3636+ sub.a r19, r19, #13737+ bne 1b3838+ ldm.w (r17 - r19, pc), [sp]+3939+ENDPROC(copy_page)
+214
arch/unicore32/lib/copy_template.S
···11+/*22+ * linux/arch/unicore32/lib/copy_template.S33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ */1212+1313+/*1414+ * Theory of operation1515+ * -------------------1616+ *1717+ * This file provides the core code for a forward memory copy used in1818+ * the implementation of memcopy(), copy_to_user() and copy_from_user().1919+ *2020+ * The including file must define the following accessor macros2121+ * according to the need of the given function:2222+ *2323+ * ldr1w ptr reg abort2424+ *2525+ * This loads one word from 'ptr', stores it in 'reg' and increments2626+ * 'ptr' to the next word. The 'abort' argument is used for fixup tables.2727+ *2828+ * ldr4w ptr reg1 reg2 reg3 reg4 abort2929+ * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort3030+ *3131+ * This loads four or eight words starting from 'ptr', stores them3232+ * in provided registers and increments 'ptr' past those words.3333+ * The'abort' argument is used for fixup tables.3434+ *3535+ * ldr1b ptr reg cond abort3636+ *3737+ * Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.3838+ * It also must apply the condition code if provided, otherwise the3939+ * "al" condition is assumed by default.4040+ *4141+ * str1w ptr reg abort4242+ * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort4343+ * str1b ptr reg cond abort4444+ *4545+ * Same as their ldr* counterparts, but data is stored to 'ptr' location4646+ * rather than being loaded.4747+ *4848+ * enter4949+ *5050+ * Preserve the provided registers on the stack plus any additional5151+ * data as needed by the implementation including this code. Called5252+ * upon code entry.5353+ *5454+ * exit5555+ *5656+ * Restore registers with the values previously saved with the5757+ * 'preserv' macro. Called upon code termination.5858+ */5959+6060+6161+ enter6262+6363+ sub.a r2, r2, #46464+ bsl 8f6565+ and.a ip, r0, #36666+ bne 9f6767+ and.a ip, r1, #36868+ bne 10f6969+7070+1: sub.a r2, r2, #(28)7171+ stm.w (r5 - r8), [sp-]7272+ bsl 5f7373+7474+3:7575+4: ldr8w r1, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f7676+ sub.a r2, r2, #327777+ str8w r0, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f7878+ beg 3b7979+8080+5: and.a ip, r2, #288181+ rsub ip, ip, #328282+ beq 7f8383+ add pc, pc, ip @ C is always clear here8484+ nop8585+8686+ ldr1w r1, r3, abort=20f8787+ ldr1w r1, r4, abort=20f8888+ ldr1w r1, r5, abort=20f8989+ ldr1w r1, r6, abort=20f9090+ ldr1w r1, r7, abort=20f9191+ ldr1w r1, r8, abort=20f9292+ ldr1w r1, r11, abort=20f9393+9494+ add pc, pc, ip9595+ nop9696+9797+ str1w r0, r3, abort=20f9898+ str1w r0, r4, abort=20f9999+ str1w r0, r5, abort=20f100100+ str1w r0, r6, abort=20f101101+ str1w r0, r7, abort=20f102102+ str1w r0, r8, abort=20f103103+ str1w r0, r11, abort=20f104104+105105+7: ldm.w (r5 - r8), [sp]+106106+107107+8: mov.a r2, r2 << #31108108+ ldr1b r1, r3, ne, abort=21f109109+ ldr1b r1, r4, ea, abort=21f110110+ ldr1b r1, r10, ea, abort=21f111111+ str1b r0, r3, ne, abort=21f112112+ str1b r0, r4, ea, abort=21f113113+ str1b r0, r10, ea, abort=21f114114+115115+ exit116116+117117+9: rsub ip, ip, #4118118+ csub.a ip, #2119119+ ldr1b r1, r3, sg, abort=21f120120+ ldr1b r1, r4, eg, abort=21f121121+ ldr1b r1, r11, abort=21f122122+ str1b r0, r3, sg, abort=21f123123+ str1b r0, r4, eg, abort=21f124124+ sub.a r2, r2, ip125125+ str1b r0, r11, abort=21f126126+ bsl 8b127127+ and.a ip, r1, #3128128+ beq 1b129129+130130+10: andn r1, r1, #3131131+ csub.a ip, #2132132+ ldr1w r1, r11, abort=21f133133+ beq 17f134134+ bsg 18f135135+136136+137137+ .macro forward_copy_shift a b138138+139139+ sub.a r2, r2, #28140140+ bsl 14f141141+142142+11: stm.w (r5 - r9), [sp-]143143+144144+12:145145+ ldr4w r1, r4, r5, r6, r7, abort=19f146146+ mov r3, r11 pull #\a147147+ sub.a r2, r2, #32148148+ ldr4w r1, r8, r9, r10, r11, abort=19f149149+ or r3, r3, r4 push #\b150150+ mov r4, r4 pull #\a151151+ or r4, r4, r5 push #\b152152+ mov r5, r5 pull #\a153153+ or r5, r5, r6 push #\b154154+ mov r6, r6 pull #\a155155+ or r6, r6, r7 push #\b156156+ mov r7, r7 pull #\a157157+ or r7, r7, r8 push #\b158158+ mov r8, r8 pull #\a159159+ or r8, r8, r9 push #\b160160+ mov r9, r9 pull #\a161161+ or r9, r9, r10 push #\b162162+ mov r10, r10 pull #\a163163+ or r10, r10, r11 push #\b164164+ str8w r0, r3, r4, r5, r6, r7, r8, r9, r10, , abort=19f165165+ beg 12b166166+167167+ ldm.w (r5 - r9), [sp]+168168+169169+14: and.a ip, r2, #28170170+ beq 16f171171+172172+15: mov r3, r11 pull #\a173173+ ldr1w r1, r11, abort=21f174174+ sub.a ip, ip, #4175175+ or r3, r3, r11 push #\b176176+ str1w r0, r3, abort=21f177177+ bsg 15b178178+179179+16: sub r1, r1, #(\b / 8)180180+ b 8b181181+182182+ .endm183183+184184+185185+ forward_copy_shift a=8 b=24186186+187187+17: forward_copy_shift a=16 b=16188188+189189+18: forward_copy_shift a=24 b=8190190+191191+192192+/*193193+ * Abort preamble and completion macros.194194+ * If a fixup handler is required then those macros must surround it.195195+ * It is assumed that the fixup code will handle the private part of196196+ * the exit macro.197197+ */198198+199199+ .macro copy_abort_preamble200200+19: ldm.w (r5 - r9), [sp]+201201+ b 21f202202+299: .word 0 @ store lr203203+ @ to avoid function call in fixup204204+20: ldm.w (r5 - r8), [sp]+205205+21:206206+ adr r1, 299b207207+ stw lr, [r1]208208+ .endm209209+210210+ .macro copy_abort_end211211+ adr lr, 299b212212+ ldw pc, [lr]213213+ .endm214214+
+96
arch/unicore32/lib/copy_to_user.S
···11+/*22+ * linux/arch/unicore32/lib/copy_to_user.S33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ */1212+1313+#include <linux/linkage.h>1414+#include <asm/assembler.h>1515+1616+/*1717+ * Prototype:1818+ *1919+ * size_t __copy_to_user(void *to, const void *from, size_t n)2020+ *2121+ * Purpose:2222+ *2323+ * copy a block to user memory from kernel memory2424+ *2525+ * Params:2626+ *2727+ * to = user memory2828+ * from = kernel memory2929+ * n = number of bytes to copy3030+ *3131+ * Return value:3232+ *3333+ * Number of bytes NOT copied.3434+ */3535+3636+ .macro ldr1w ptr reg abort3737+ ldw.w \reg, [\ptr]+, #43838+ .endm3939+4040+ .macro ldr4w ptr reg1 reg2 reg3 reg4 abort4141+ ldm.w (\reg1, \reg2, \reg3, \reg4), [\ptr]+4242+ .endm4343+4444+ .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort4545+ ldm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+4646+ .endm4747+4848+ .macro ldr1b ptr reg cond=al abort4949+ notcond \cond, .+85050+ ldb.w \reg, [\ptr]+, #15151+ .endm5252+5353+ .macro str1w ptr reg abort5454+ strusr \reg, \ptr, 4, abort=\abort5555+ .endm5656+5757+ .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort5858+100: stm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+5959+6060+ .pushsection __ex_table, "a"6161+ .long 100b, \abort6262+ .popsection6363+ .endm6464+6565+ .macro str1b ptr reg cond=al abort6666+ strusr \reg, \ptr, 1, \cond, abort=\abort6767+ .endm6868+6969+ .macro enter7070+ mov r3, #07171+ stm.w (r0, r2, r3), [sp-]7272+ .endm7373+7474+ .macro exit7575+ add sp, sp, #87676+ ldm.w (r0), [sp]+7777+ mov pc, lr7878+ .endm7979+8080+ .text8181+8282+WEAK(__copy_to_user)8383+8484+#include "copy_template.S"8585+8686+ENDPROC(__copy_to_user)8787+8888+ .pushsection .fixup,"ax"8989+ .align 09090+ copy_abort_preamble9191+ ldm.w (r1, r2, r3), [sp]+9292+ sub r0, r0, r19393+ rsub r0, r0, r29494+ copy_abort_end9595+ .popsection9696+
+45
arch/unicore32/lib/strncpy_from_user.S
···11+/*22+ * linux/arch/unicore32/lib/strncpy_from_user.S33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ */1212+#include <linux/linkage.h>1313+#include <asm/assembler.h>1414+#include <asm/errno.h>1515+1616+ .text1717+ .align 51818+1919+/*2020+ * Copy a string from user space to kernel space.2121+ * r0 = dst, r1 = src, r2 = byte length2222+ * returns the number of characters copied (strlen of copied string),2323+ * -EFAULT on exception, or "len" if we fill the whole buffer2424+ */2525+ENTRY(__strncpy_from_user)2626+ mov ip, r12727+1: sub.a r2, r2, #12828+ ldrusr r3, r1, 1, ns2929+ bfs 2f3030+ stb.w r3, [r0]+, #13131+ cxor.a r3, #03232+ bne 1b3333+ sub r1, r1, #1 @ take NUL character out of count3434+2: sub r0, r1, ip3535+ mov pc, lr3636+ENDPROC(__strncpy_from_user)3737+3838+ .pushsection .fixup,"ax"3939+ .align 04040+9001: mov r3, #04141+ stb r3, [r0+], #0 @ null terminate4242+ mov r0, #-EFAULT4343+ mov pc, lr4444+ .popsection4545+
+42
arch/unicore32/lib/strnlen_user.S
···11+/*22+ * linux/arch/unicore32/lib/strnlen_user.S33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ */1212+#include <linux/linkage.h>1313+#include <asm/assembler.h>1414+#include <asm/errno.h>1515+1616+ .text1717+ .align 51818+1919+/* Prototype: unsigned long __strnlen_user(const char *str, long n)2020+ * Purpose : get length of a string in user memory2121+ * Params : str - address of string in user memory2222+ * Returns : length of string *including terminator*2323+ * or zero on exception, or n + 1 if too long2424+ */2525+ENTRY(__strnlen_user)2626+ mov r2, r02727+1:2828+ ldrusr r3, r0, 12929+ cxor.a r3, #03030+ beq 2f3131+ sub.a r1, r1, #13232+ bne 1b3333+ add r0, r0, #13434+2: sub r0, r0, r23535+ mov pc, lr3636+ENDPROC(__strnlen_user)3737+3838+ .pushsection .fixup,"ax"3939+ .align 04040+9001: mov r0, #04141+ mov pc, lr4242+ .popsection