Logo Search packages:      
Sourcecode: linux version File versions  Download package

uaccess_32.h

/*
 * User space memory access functions
 *
 * Copyright (C) 1999, 2002  Niibe Yutaka
 * Copyright (C) 2003 - 2008  Paul Mundt
 *
 *  Based on:
 *     MIPS implementation version 1.15 by
 *              Copyright (C) 1996, 1997, 1998 by Ralf Baechle
 *     and i386 version.
 */
#ifndef __ASM_SH_UACCESS_32_H
#define __ASM_SH_UACCESS_32_H

#define __get_user_size(x,ptr,size,retval)                  \
do {                                            \
      retval = 0;                               \
      switch (size) {                                 \
      case 1:                                         \
            __get_user_asm(x, ptr, retval, "b");            \
            break;                                    \
      case 2:                                         \
            __get_user_asm(x, ptr, retval, "w");            \
            break;                                    \
      case 4:                                         \
            __get_user_asm(x, ptr, retval, "l");            \
            break;                                    \
      default:                                  \
            __get_user_unknown();                     \
            break;                                    \
      }                                         \
} while (0)

#ifdef CONFIG_MMU
#define __get_user_asm(x, addr, err, insn) \
({ \
__asm__ __volatile__( \
      "1:\n\t" \
      "mov." insn "     %2, %1\n\t" \
      "2:\n" \
      ".section   .fixup,\"ax\"\n" \
      "3:\n\t" \
      "mov  #0, %1\n\t" \
      "mov.l      4f, %0\n\t" \
      "jmp  @%0\n\t" \
      " mov %3, %0\n\t" \
      ".balign    4\n" \
      "4:   .long 2b\n\t" \
      ".previous\n" \
      ".section   __ex_table,\"a\"\n\t" \
      ".long      1b, 3b\n\t" \
      ".previous" \
      :"=&r" (err), "=&r" (x) \
      :"m" (__m(addr)), "i" (-EFAULT), "0" (err)); })
#else
#define __get_user_asm(x, addr, err, insn)            \
do {                                      \
      __asm__ __volatile__ (                    \
            "mov." insn "     %1, %0\n\t"       \
            : "=&r" (x)                   \
            : "m" (__m(addr))             \
      );                                  \
} while (0)
#endif /* CONFIG_MMU */

extern void __get_user_unknown(void);

#define __put_user_size(x,ptr,size,retval)            \
do {                                      \
      retval = 0;                         \
      switch (size) {                           \
      case 1:                                   \
            __put_user_asm(x, ptr, retval, "b");      \
            break;                              \
      case 2:                                   \
            __put_user_asm(x, ptr, retval, "w");      \
            break;                              \
      case 4:                                   \
            __put_user_asm(x, ptr, retval, "l");      \
            break;                              \
      case 8:                                   \
            __put_user_u64(x, ptr, retval);           \
            break;                              \
      default:                            \
            __put_user_unknown();               \
      }                                   \
} while (0)

#ifdef CONFIG_MMU
#define __put_user_asm(x, addr, err, insn)                  \
do {                                            \
      __asm__ __volatile__ (                          \
            "1:\n\t"                            \
            "mov." insn "     %1, %2\n\t"             \
            "2:\n"                                    \
            ".section   .fixup,\"ax\"\n"        \
            "3:\n\t"                            \
            "mov.l      4f, %0\n\t"                   \
            "jmp  @%0\n\t"                      \
            " mov %3, %0\n\t"                   \
            ".balign    4\n"                    \
            "4:   .long 2b\n\t"                       \
            ".previous\n"                             \
            ".section   __ex_table,\"a\"\n\t"         \
            ".long      1b, 3b\n\t"                   \
            ".previous"                         \
            : "=&r" (err)                             \
            : "r" (x), "m" (__m(addr)), "i" (-EFAULT),      \
              "0" (err)                         \
            : "memory"                          \
      );                                        \
} while (0)
#else
#define __put_user_asm(x, addr, err, insn)            \
do {                                      \
      __asm__ __volatile__ (                    \
            "mov." insn "     %0, %1\n\t"       \
            : /* no outputs */                  \
            : "r" (x), "m" (__m(addr))          \
            : "memory"                    \
      );                                  \
} while (0)
#endif /* CONFIG_MMU */

#if defined(CONFIG_CPU_LITTLE_ENDIAN)
#define __put_user_u64(val,addr,retval) \
({ \
__asm__ __volatile__( \
      "1:\n\t" \
      "mov.l      %R1,%2\n\t" \
      "mov.l      %S1,%T2\n\t" \
      "2:\n" \
      ".section   .fixup,\"ax\"\n" \
      "3:\n\t" \
      "mov.l      4f,%0\n\t" \
      "jmp  @%0\n\t" \
      " mov %3,%0\n\t" \
      ".balign    4\n" \
      "4:   .long 2b\n\t" \
      ".previous\n" \
      ".section   __ex_table,\"a\"\n\t" \
      ".long      1b, 3b\n\t" \
      ".previous" \
      : "=r" (retval) \
      : "r" (val), "m" (__m(addr)), "i" (-EFAULT), "0" (retval) \
        : "memory"); })
#else
#define __put_user_u64(val,addr,retval) \
({ \
__asm__ __volatile__( \
      "1:\n\t" \
      "mov.l      %S1,%2\n\t" \
      "mov.l      %R1,%T2\n\t" \
      "2:\n" \
      ".section   .fixup,\"ax\"\n" \
      "3:\n\t" \
      "mov.l      4f,%0\n\t" \
      "jmp  @%0\n\t" \
      " mov %3,%0\n\t" \
      ".balign    4\n" \
      "4:   .long 2b\n\t" \
      ".previous\n" \
      ".section   __ex_table,\"a\"\n\t" \
      ".long      1b, 3b\n\t" \
      ".previous" \
      : "=r" (retval) \
      : "r" (val), "m" (__m(addr)), "i" (-EFAULT), "0" (retval) \
        : "memory"); })
#endif

extern void __put_user_unknown(void);

static inline int
__strncpy_from_user(unsigned long __dest, unsigned long __user __src, int __count)
{
      __kernel_size_t res;
      unsigned long __dummy, _d, _s, _c;

      __asm__ __volatile__(
            "9:\n"
            "mov.b      @%2+, %1\n\t"
            "cmp/eq     #0, %1\n\t"
            "bt/s 2f\n"
            "1:\n"
            "mov.b      %1, @%3\n\t"
            "dt   %4\n\t"
            "bf/s 9b\n\t"
            " add #1, %3\n\t"
            "2:\n\t"
            "sub  %4, %0\n"
            "3:\n"
            ".section .fixup,\"ax\"\n"
            "4:\n\t"
            "mov.l      5f, %1\n\t"
            "jmp  @%1\n\t"
            " mov %9, %0\n\t"
            ".balign 4\n"
            "5:   .long 3b\n"
            ".previous\n"
            ".section __ex_table,\"a\"\n"
            "     .balign 4\n"
            "     .long 9b,4b\n"
            ".previous"
            : "=r" (res), "=&z" (__dummy), "=r" (_s), "=r" (_d), "=r"(_c)
            : "0" (__count), "2" (__src), "3" (__dest), "4" (__count),
              "i" (-EFAULT)
            : "memory", "t");

      return res;
}

/*
 * Return the size of a string (including the ending 0 even when we have
 * exceeded the maximum string length).
 */
static inline long __strnlen_user(const char __user *__s, long __n)
{
      unsigned long res;
      unsigned long __dummy;

      __asm__ __volatile__(
            "1:\t"
            "mov.b      @(%0,%3), %1\n\t"
            "cmp/eq     %4, %0\n\t"
            "bt/s 2f\n\t"
            " add #1, %0\n\t"
            "tst  %1, %1\n\t"
            "bf   1b\n\t"
            "2:\n"
            ".section .fixup,\"ax\"\n"
            "3:\n\t"
            "mov.l      4f, %1\n\t"
            "jmp  @%1\n\t"
            " mov #0, %0\n"
            ".balign 4\n"
            "4:   .long 2b\n"
            ".previous\n"
            ".section __ex_table,\"a\"\n"
            "     .balign 4\n"
            "     .long 1b,3b\n"
            ".previous"
            : "=z" (res), "=&r" (__dummy)
            : "0" (0), "r" (__s), "r" (__n)
            : "t");
      return res;
}

#endif /* __ASM_SH_UACCESS_32_H */

Generated by  Doxygen 1.6.0   Back to index