linux/arch/microblaze/lib/uaccess_old.S
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
   3 * Copyright (C) 2009 PetaLogix
   4 * Copyright (C) 2007 LynuxWorks, Inc.
   5 *
   6 * This file is subject to the terms and conditions of the GNU General Public
   7 * License.  See the file "COPYING" in the main directory of this archive
   8 * for more details.
   9 */
  10
  11#include <linux/errno.h>
  12#include <linux/linkage.h>
  13#include <asm/page.h>
  14
  15/*
  16 * int __strncpy_user(char *to, char *from, int len);
  17 *
  18 * Returns:
  19 *  -EFAULT  for an exception
  20 *  len      if we hit the buffer limit
  21 *  bytes copied
  22 */
  23
  24        .text
  25.globl __strncpy_user;
  26.type  __strncpy_user, @function
  27.align 4;
  28__strncpy_user:
  29
  30        /*
  31         * r5 - to
  32         * r6 - from
  33         * r7 - len
  34         * r3 - temp count
  35         * r4 - temp val
  36         */
  37        beqid   r7,3f
  38        addik   r3,r7,0         /* temp_count = len */
  391:
  40        lbu     r4,r6,r0
  41        beqid   r4,2f
  42        sb      r4,r5,r0
  43
  44        addik   r5,r5,1
  45        addik   r6,r6,1         /* delay slot */
  46
  47        addik   r3,r3,-1
  48        bnei    r3,1b           /* break on len */
  492:
  50        rsubk   r3,r3,r7        /* temp_count = len - temp_count */
  513:
  52        rtsd    r15,8
  53        nop
  54        .size   __strncpy_user, . - __strncpy_user
  55
  56        .section        .fixup, "ax"
  57        .align  2
  584:
  59        brid    3b
  60        addik   r3,r0, -EFAULT
  61
  62        .section        __ex_table, "a"
  63        .word   1b,4b
  64
  65/*
  66 * int __strnlen_user(char __user *str, int maxlen);
  67 *
  68 * Returns:
  69 *  0 on error
  70 *  maxlen + 1  if no NUL byte found within maxlen bytes
  71 *  size of the string (including NUL byte)
  72 */
  73
  74        .text
  75.globl __strnlen_user;
  76.type  __strnlen_user, @function
  77.align 4;
  78__strnlen_user:
  79        beqid   r6,3f
  80        addik   r3,r6,0
  811:
  82        lbu     r4,r5,r0
  83        beqid   r4,2f           /* break on NUL */
  84        addik   r3,r3,-1        /* delay slot */
  85
  86        bneid   r3,1b
  87        addik   r5,r5,1         /* delay slot */
  88
  89        addik   r3,r3,-1        /* for break on len */
  902:
  91        rsubk   r3,r3,r6
  923:
  93        rtsd    r15,8
  94        nop
  95        .size   __strnlen_user, . - __strnlen_user
  96
  97        .section        .fixup,"ax"
  984:
  99        brid    3b
 100        addk    r3,r0,r0
 101
 102        .section        __ex_table,"a"
 103        .word   1b,4b
 104
 105/* Loop unrolling for __copy_tofrom_user */
 106#define COPY(offset)    \
 1071:      lwi     r4 , r6, 0x0000 + offset;       \
 1082:      lwi     r19, r6, 0x0004 + offset;       \
 1093:      lwi     r20, r6, 0x0008 + offset;       \
 1104:      lwi     r21, r6, 0x000C + offset;       \
 1115:      lwi     r22, r6, 0x0010 + offset;       \
 1126:      lwi     r23, r6, 0x0014 + offset;       \
 1137:      lwi     r24, r6, 0x0018 + offset;       \
 1148:      lwi     r25, r6, 0x001C + offset;       \
 1159:      swi     r4 , r5, 0x0000 + offset;       \
 11610:     swi     r19, r5, 0x0004 + offset;       \
 11711:     swi     r20, r5, 0x0008 + offset;       \
 11812:     swi     r21, r5, 0x000C + offset;       \
 11913:     swi     r22, r5, 0x0010 + offset;       \
 12014:     swi     r23, r5, 0x0014 + offset;       \
 12115:     swi     r24, r5, 0x0018 + offset;       \
 12216:     swi     r25, r5, 0x001C + offset;       \
 123        .section __ex_table,"a";                \
 124        .word   1b, 33f;                        \
 125        .word   2b, 33f;                        \
 126        .word   3b, 33f;                        \
 127        .word   4b, 33f;                        \
 128        .word   5b, 33f;                        \
 129        .word   6b, 33f;                        \
 130        .word   7b, 33f;                        \
 131        .word   8b, 33f;                        \
 132        .word   9b, 33f;                        \
 133        .word   10b, 33f;                       \
 134        .word   11b, 33f;                       \
 135        .word   12b, 33f;                       \
 136        .word   13b, 33f;                       \
 137        .word   14b, 33f;                       \
 138        .word   15b, 33f;                       \
 139        .word   16b, 33f;                       \
 140        .text
 141
 142#define COPY_80(offset) \
 143        COPY(0x00 + offset);\
 144        COPY(0x20 + offset);\
 145        COPY(0x40 + offset);\
 146        COPY(0x60 + offset);
 147
 148/*
 149 * int __copy_tofrom_user(char *to, char *from, int len)
 150 * Return:
 151 *   0 on success
 152 *   number of not copied bytes on error
 153 */
 154        .text
 155.globl __copy_tofrom_user;
 156.type  __copy_tofrom_user, @function
 157.align 4;
 158__copy_tofrom_user:
 159        /*
 160         * r5 - to
 161         * r6 - from
 162         * r7, r3 - count
 163         * r4 - tempval
 164         */
 165        beqid   r7, 0f /* zero size is not likely */
 166        or      r3, r5, r6 /* find if is any to/from unaligned */
 167        or      r3, r3, r7 /* find if count is unaligned */
 168        andi    r3, r3, 0x3 /* mask last 3 bits */
 169        bneid   r3, bu1 /* if r3 is not zero then byte copying */
 170        or      r3, r0, r0
 171
 172        rsubi   r3, r7, PAGE_SIZE /* detect PAGE_SIZE */
 173        beqid   r3, page;
 174        or      r3, r0, r0
 175
 176w1:     lw      r4, r6, r3 /* at least one 4 byte copy */
 177w2:     sw      r4, r5, r3
 178        addik   r7, r7, -4
 179        bneid   r7, w1
 180        addik   r3, r3, 4
 181        addik   r3, r7, 0
 182        rtsd    r15, 8
 183        nop
 184
 185        .section        __ex_table,"a"
 186        .word   w1, 0f;
 187        .word   w2, 0f;
 188        .text
 189
 190.align 4 /* Alignment is important to keep icache happy */
 191page:   /* Create room on stack and save registers for storign values */
 192        addik   r1, r1, -40
 193        swi     r5, r1, 0
 194        swi     r6, r1, 4
 195        swi     r7, r1, 8
 196        swi     r19, r1, 12
 197        swi     r20, r1, 16
 198        swi     r21, r1, 20
 199        swi     r22, r1, 24
 200        swi     r23, r1, 28
 201        swi     r24, r1, 32
 202        swi     r25, r1, 36
 203loop:   /* r4, r19, r20, r21, r22, r23, r24, r25 are used for storing values */
 204        /* Loop unrolling to get performance boost */
 205        COPY_80(0x000);
 206        COPY_80(0x080);
 207        COPY_80(0x100);
 208        COPY_80(0x180);
 209        /* copy loop */
 210        addik   r6, r6, 0x200
 211        addik   r7, r7, -0x200
 212        bneid   r7, loop
 213        addik   r5, r5, 0x200
 214
 215        /* Restore register content */
 216        lwi     r5, r1, 0
 217        lwi     r6, r1, 4
 218        lwi     r7, r1, 8
 219        lwi     r19, r1, 12
 220        lwi     r20, r1, 16
 221        lwi     r21, r1, 20
 222        lwi     r22, r1, 24
 223        lwi     r23, r1, 28
 224        lwi     r24, r1, 32
 225        lwi     r25, r1, 36
 226        addik   r1, r1, 40
 227        /* return back */
 228        addik   r3, r0, 0
 229        rtsd    r15, 8
 230        nop
 231
 232/* Fault case - return temp count */
 23333:
 234        addik   r3, r7, 0
 235        /* Restore register content */
 236        lwi     r5, r1, 0
 237        lwi     r6, r1, 4
 238        lwi     r7, r1, 8
 239        lwi     r19, r1, 12
 240        lwi     r20, r1, 16
 241        lwi     r21, r1, 20
 242        lwi     r22, r1, 24
 243        lwi     r23, r1, 28
 244        lwi     r24, r1, 32
 245        lwi     r25, r1, 36
 246        addik   r1, r1, 40
 247        /* return back */
 248        rtsd    r15, 8
 249        nop
 250
 251.align 4 /* Alignment is important to keep icache happy */
 252bu1:    lbu     r4,r6,r3
 253bu2:    sb      r4,r5,r3
 254        addik   r7,r7,-1
 255        bneid   r7,bu1
 256        addik   r3,r3,1         /* delay slot */
 2570:
 258        addik   r3,r7,0
 259        rtsd    r15,8
 260        nop
 261        .size   __copy_tofrom_user, . - __copy_tofrom_user
 262
 263        .section        __ex_table,"a"
 264        .word   bu1, 0b;
 265        .word   bu2, 0b;
 266        .text
 267