Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
0003 
0004 #include <linux/uaccess.h>
0005 #include <linux/types.h>
0006 
0007 unsigned long raw_copy_from_user(void *to, const void *from,
0008             unsigned long n)
0009 {
0010     int tmp, nsave;
0011 
0012     __asm__ __volatile__(
0013     "0:     cmpnei  %1, 0           \n"
0014     "       bf      7f              \n"
0015     "       mov     %3, %1          \n"
0016     "       or      %3, %2          \n"
0017     "       andi    %3, 3           \n"
0018     "       cmpnei  %3, 0           \n"
0019     "       bf      1f              \n"
0020     "       br      5f              \n"
0021     "1:     cmplti  %0, 16          \n"
0022     "       bt      3f              \n"
0023     "2:     ldw     %3, (%2, 0)     \n"
0024     "10:    ldw     %4, (%2, 4)     \n"
0025     "       stw     %3, (%1, 0)     \n"
0026     "       stw     %4, (%1, 4)     \n"
0027     "11:    ldw     %3, (%2, 8)     \n"
0028     "12:    ldw     %4, (%2, 12)    \n"
0029     "       stw     %3, (%1, 8)     \n"
0030     "       stw     %4, (%1, 12)    \n"
0031     "       addi    %2, 16          \n"
0032     "       addi    %1, 16          \n"
0033     "       subi    %0, 16          \n"
0034     "       br      1b              \n"
0035     "3:     cmplti  %0, 4           \n"
0036     "       bt      5f              \n"
0037     "4:     ldw     %3, (%2, 0)     \n"
0038     "       stw     %3, (%1, 0)     \n"
0039     "       addi    %2, 4           \n"
0040     "       addi    %1, 4           \n"
0041     "       subi    %0, 4           \n"
0042     "       br      3b              \n"
0043     "5:     cmpnei  %0, 0           \n"
0044     "       bf      7f              \n"
0045     "6:     ldb     %3, (%2, 0)     \n"
0046     "       stb     %3, (%1, 0)     \n"
0047     "       addi    %2,  1          \n"
0048     "       addi    %1,  1          \n"
0049     "       subi    %0,  1          \n"
0050     "       br      5b              \n"
0051     "8:     stw     %3, (%1, 0)     \n"
0052     "       subi    %0, 4           \n"
0053     "       bf      7f              \n"
0054     "9:     subi    %0, 8           \n"
0055     "       bf      7f              \n"
0056     "13:    stw     %3, (%1, 8)     \n"
0057     "       subi    %0, 12          \n"
0058     "       bf      7f              \n"
0059     ".section __ex_table, \"a\"     \n"
0060     ".align   2                     \n"
0061     ".long    2b, 7f                \n"
0062     ".long    4b, 7f                \n"
0063     ".long    6b, 7f                \n"
0064     ".long   10b, 8b                \n"
0065     ".long   11b, 9b                \n"
0066     ".long   12b,13b                \n"
0067     ".previous                      \n"
0068     "7:                             \n"
0069     : "=r"(n), "=r"(to), "=r"(from), "=r"(nsave),
0070       "=r"(tmp)
0071     : "0"(n), "1"(to), "2"(from)
0072     : "memory");
0073 
0074     return n;
0075 }
0076 EXPORT_SYMBOL(raw_copy_from_user);
0077 
0078 unsigned long raw_copy_to_user(void *to, const void *from,
0079             unsigned long n)
0080 {
0081     int w0, w1, w2, w3;
0082 
0083     __asm__ __volatile__(
0084     "0:     cmpnei  %1, 0           \n"
0085     "       bf      8f              \n"
0086     "       mov     %3, %1          \n"
0087     "       or      %3, %2          \n"
0088     "       andi    %3, 3           \n"
0089     "       cmpnei  %3, 0           \n"
0090     "       bf      1f              \n"
0091     "       br      5f              \n"
0092     "1:     cmplti  %0, 16          \n" /* 4W */
0093     "       bt      3f              \n"
0094     "       ldw     %3, (%2, 0)     \n"
0095     "       ldw     %4, (%2, 4)     \n"
0096     "       ldw     %5, (%2, 8)     \n"
0097     "       ldw     %6, (%2, 12)    \n"
0098     "2:     stw     %3, (%1, 0)     \n"
0099     "9:     stw     %4, (%1, 4)     \n"
0100     "10:    stw     %5, (%1, 8)     \n"
0101     "11:    stw     %6, (%1, 12)    \n"
0102     "       addi    %2, 16          \n"
0103     "       addi    %1, 16          \n"
0104     "       subi    %0, 16          \n"
0105     "       br      1b              \n"
0106     "3:     cmplti  %0, 4           \n" /* 1W */
0107     "       bt      5f              \n"
0108     "       ldw     %3, (%2, 0)     \n"
0109     "4:     stw     %3, (%1, 0)     \n"
0110     "       addi    %2, 4           \n"
0111     "       addi    %1, 4           \n"
0112     "       subi    %0, 4           \n"
0113     "       br      3b              \n"
0114     "5:     cmpnei  %0, 0           \n"  /* 1B */
0115     "       bf      13f             \n"
0116     "       ldb     %3, (%2, 0)     \n"
0117     "6:     stb     %3, (%1, 0)     \n"
0118     "       addi    %2,  1          \n"
0119     "       addi    %1,  1          \n"
0120     "       subi    %0,  1          \n"
0121     "       br      5b              \n"
0122     "7:     subi    %0,  4          \n"
0123     "8:     subi    %0,  4          \n"
0124     "12:    subi    %0,  4          \n"
0125     "       br      13f             \n"
0126     ".section __ex_table, \"a\"     \n"
0127     ".align   2                     \n"
0128     ".long    2b, 13f               \n"
0129     ".long    4b, 13f               \n"
0130     ".long    6b, 13f               \n"
0131     ".long    9b, 12b               \n"
0132     ".long   10b, 8b                \n"
0133     ".long   11b, 7b                \n"
0134     ".previous                      \n"
0135     "13:                            \n"
0136     : "=r"(n), "=r"(to), "=r"(from), "=r"(w0),
0137       "=r"(w1), "=r"(w2), "=r"(w3)
0138     : "0"(n), "1"(to), "2"(from)
0139     : "memory");
0140 
0141     return n;
0142 }
0143 EXPORT_SYMBOL(raw_copy_to_user);
0144 
0145 /*
0146  * __clear_user: - Zero a block of memory in user space, with less checking.
0147  * @to:   Destination address, in user space.
0148  * @n:    Number of bytes to zero.
0149  *
0150  * Zero a block of memory in user space.  Caller must check
0151  * the specified block with access_ok() before calling this function.
0152  *
0153  * Returns number of bytes that could not be cleared.
0154  * On success, this will be zero.
0155  */
0156 unsigned long
0157 __clear_user(void __user *to, unsigned long n)
0158 {
0159     int data, value, tmp;
0160 
0161     __asm__ __volatile__(
0162     "0:     cmpnei  %1, 0           \n"
0163     "       bf      7f              \n"
0164     "       mov     %3, %1          \n"
0165     "       andi    %3, 3           \n"
0166     "       cmpnei  %3, 0           \n"
0167     "       bf      1f              \n"
0168     "       br      5f              \n"
0169     "1:     cmplti  %0, 32          \n" /* 4W */
0170     "       bt      3f              \n"
0171     "8:     stw     %2, (%1, 0)     \n"
0172     "10:    stw     %2, (%1, 4)     \n"
0173     "11:    stw     %2, (%1, 8)     \n"
0174     "12:    stw     %2, (%1, 12)    \n"
0175     "13:    stw     %2, (%1, 16)    \n"
0176     "14:    stw     %2, (%1, 20)    \n"
0177     "15:    stw     %2, (%1, 24)    \n"
0178     "16:    stw     %2, (%1, 28)    \n"
0179     "       addi    %1, 32          \n"
0180     "       subi    %0, 32          \n"
0181     "       br      1b              \n"
0182     "3:     cmplti  %0, 4           \n" /* 1W */
0183     "       bt      5f              \n"
0184     "4:     stw     %2, (%1, 0)     \n"
0185     "       addi    %1, 4           \n"
0186     "       subi    %0, 4           \n"
0187     "       br      3b              \n"
0188     "5:     cmpnei  %0, 0           \n" /* 1B */
0189     "9:     bf      7f              \n"
0190     "6:     stb     %2, (%1, 0)     \n"
0191     "       addi    %1,  1          \n"
0192     "       subi    %0,  1          \n"
0193     "       br      5b              \n"
0194     ".section __ex_table,\"a\"      \n"
0195     ".align   2                     \n"
0196     ".long    8b, 9b                \n"
0197     ".long    10b, 9b               \n"
0198     ".long    11b, 9b               \n"
0199     ".long    12b, 9b               \n"
0200     ".long    13b, 9b               \n"
0201     ".long    14b, 9b               \n"
0202     ".long    15b, 9b               \n"
0203     ".long    16b, 9b               \n"
0204     ".long    4b, 9b                \n"
0205     ".long    6b, 9b                \n"
0206     ".previous                      \n"
0207     "7:                             \n"
0208     : "=r"(n), "=r" (data), "=r"(value), "=r"(tmp)
0209     : "0"(n), "1"(to), "2"(0)
0210     : "memory");
0211 
0212     return n;
0213 }
0214 EXPORT_SYMBOL(__clear_user);