home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / include / asm-m68k / segment.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-29  |  5.4 KB  |  242 lines

  1. /*
  2.  *  linux/include/asm-m68k/segment.h
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  *
  6.  * This file is subject to the terms and conditions of the GNU General Public
  7.  * License.  See the file README.legal in the main directory of this archive
  8.  * for more details.
  9.  */
  10.  
  11. /*
  12.  * 680x0 support added by Hamish Macdonald
  13.  */
  14.  
  15. #ifndef _M68K_SEGMENT_H
  16. #define _M68K_SEGMENT_H
  17.  
  18. static inline unsigned char get_user_byte(const char * addr)
  19. {
  20.     register unsigned char _v;
  21.  
  22.     __asm__ __volatile__ ("movesb %1,%0":"=r" (_v):"m" (*addr));
  23.     return _v;
  24. }
  25.  
  26. #define get_fs_byte(addr) get_user_byte((char *)(addr))
  27.  
  28. static inline unsigned short get_user_word(const short *addr)
  29. {
  30.     unsigned short _v;
  31.  
  32.     __asm__ __volatile__ ("movesw %1,%0":"=r" (_v):"m" (*addr));
  33.     return _v;
  34. }
  35.  
  36. #define get_fs_word(addr) get_user_word((short *)(addr))
  37.  
  38. static inline unsigned long get_user_long(const int *addr)
  39. {
  40.     unsigned long _v;
  41.  
  42.     __asm__ __volatile__ ("movesl %1,%0":"=r" (_v):"m" (*addr)); \
  43.     return _v;
  44. }
  45.  
  46. #define get_fs_long(addr) get_user_long((int *)(addr))
  47.  
  48. static inline void put_user_byte(char val,char *addr)
  49. {
  50.     __asm__ __volatile__ ("movesb %0,%1": /* no outputs */ :"r" (val),"m" (*addr) : "memory");
  51. }
  52.  
  53. #define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr))
  54.  
  55. static inline void put_user_word(short val,short * addr)
  56. {
  57.     __asm__ __volatile__ ("movesw %0,%1": /* no outputs */ :"r" (val),"m" (*addr) : "memory");
  58. }
  59.  
  60. #define put_fs_word(x,addr) put_user_word((x),(short *)(addr))
  61.  
  62. static inline void put_user_long(unsigned long val,int * addr)
  63. {
  64.     __asm__ __volatile__ ("movesl %0,%1": /* no outputs */ :"r" (val),"m" (*addr) : "memory");
  65. }
  66.  
  67. #define put_fs_long(x,addr) put_user_long((x),(int *)(addr))
  68.  
  69. static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
  70. {
  71.     if (n == 0) return;
  72.     __asm__ __volatile__ ("1:\n\t"
  73.                   "moveb %1@+,d0\n\t"
  74.                   "movesb d0,%2@+\n\t"
  75.                   "dbra %0,1b\n\t"
  76.                   "clrw %0\n\t"
  77.                   "subql #1,%0\n\t"
  78.                   "bccs 1b"
  79.                   : "=d" (n), "=a" (from), "=a" (to)
  80.                   : "1" (from), "2" (to), "0" (n-1)
  81.                   : "d0", "memory");
  82. }
  83.  
  84. static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
  85. {
  86.     if (n == 0) {
  87.             return;
  88.     } else if (n == 1) {
  89.             put_user_byte(*(const char *) from, (char *) to);
  90.             return;
  91.     } else if (n == 2) {
  92.             put_user_word(*(const short *) from, (short *) to);
  93.             return;
  94.     } else if (n == 3) {
  95.             put_user_word(*(const short *) from, (short *) to);
  96.             put_user_byte(*(2+(const char *) from), 2+(char *) to);
  97.             return;
  98.     } else if (n == 4) {
  99.             put_user_long(*(const int *) from, (int *) to);
  100.             return;
  101.     }
  102. #if 0
  103. #define COMMON(x) \
  104. __asm__("cld\n\t" \
  105.     "push %%es\n\t" \
  106.     "push %%fs\n\t" \
  107.     "pop %%es\n\t" \
  108.     "rep ; movsl\n\t" \
  109.     x \
  110.     "pop %%es" \
  111.     : /* no outputs */ \
  112.     :"c" (n/4),"D" ((long) to),"S" ((long) from) \
  113.     :"cx","di","si")
  114.  
  115.     switch (n % 4) {
  116.         case 0:
  117.             COMMON("");
  118.             return;
  119.         case 1:
  120.             COMMON("movsb\n\t");
  121.             return;
  122.         case 2:
  123.             COMMON("movsw\n\t");
  124.             return;
  125.         case 3:
  126.             COMMON("movsw\n\tmovsb\n\t");
  127.             return;
  128.     }
  129. #undef COMMON
  130. #else
  131.         __generic_memcpy_tofs(to,from,n);
  132. #endif
  133. }
  134.  
  135. static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
  136. {
  137.     if (n == 0) return;
  138.     __asm__ __volatile__ ("1:\n\t"
  139.                   "movesb %1@+,d0\n\t"
  140.                   "moveb d0,%2@+\n\t"
  141.                   "dbra %0,1b\n\t"
  142.                   "clrw %0\n\t"
  143.                   "subql #1,%0\n\t"
  144.                   "bccs 1b"
  145.                   : "=d" (n), "=a" (from), "=a" (to)
  146.                   : "1" (from), "2" (to), "0" (n-1)
  147.                   : "d0", "memory");
  148. }
  149.  
  150. static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
  151. {
  152.     if (n == 0) {
  153.             return;
  154.     } else if (n == 1) {
  155.             *(char *)to = get_user_byte((const char *) from);
  156.             return;
  157.     } else if (n == 2) {
  158.             *(short *)to = get_user_word((const short *) from);
  159.             return;
  160.     } else if (n == 3) {
  161.             *(short *) to = get_user_word((const short *) from);
  162.             *(2+(char *) to) = get_user_byte(2+(const char *) from);
  163.             return;
  164.     } else if (n == 4) {
  165.             *(int *) to = get_user_long((const int *) from);
  166.             return;
  167.     }
  168. #if 0
  169. #define COMMON(x) \
  170. __asm__("cld\n\t" \
  171.     "rep ; fs ; movsl\n\t" \
  172.     x \
  173.     : /* no outputs */ \
  174.     :"c" (n/4),"D" ((long) to),"S" ((long) from) \
  175.     :"cx","di","si","memory")
  176.  
  177.     switch (n % 4) {
  178.         case 0:
  179.             COMMON("");
  180.             return;
  181.         case 1:
  182.             COMMON("fs ; movsb");
  183.             return;
  184.         case 2:
  185.             COMMON("fs ; movsw");
  186.             return;
  187.         case 3:
  188.             COMMON("fs ; movsw\n\tfs ; movsb");
  189.             return;
  190.     }
  191. #undef COMMON
  192. #else
  193.         __generic_memcpy_fromfs(to,from,n);
  194. #endif
  195. }
  196.  
  197. #define memcpy_fromfs(to, from, n) \
  198. (__builtin_constant_p(n) ? \
  199.  __constant_memcpy_fromfs((to),(from),(n)) : \
  200.  __generic_memcpy_fromfs((to),(from),(n)))
  201.  
  202. #define memcpy_tofs(to, from, n) \
  203. (__builtin_constant_p(n) ? \
  204.  __constant_memcpy_tofs((to),(from),(n)) : \
  205.  __generic_memcpy_tofs((to),(from),(n)))
  206.  
  207. /*
  208.  * Get/set the SFC/DFC registers for MOVES instructions
  209.  */
  210.  
  211. static inline unsigned long get_fs(void)
  212. {
  213.     unsigned long _v;
  214.     __asm__ ("movec dfc,%0":"=r" (_v):);
  215.  
  216.     return _v;
  217. }
  218.  
  219. static inline unsigned long get_ds(void)
  220. {
  221.     /* return the supervisor data space code */
  222.     return 0x5;
  223. }
  224.  
  225. static inline void set_fs(unsigned long val)
  226. {
  227.     __asm__ __volatile__ ("movec %0,sfc\n\t"
  228.                   "movec %0,dfc\n\t"
  229.                   : /* no outputs */ : "r" (val), "r" (val) : "memory");
  230. }
  231.  
  232. /* define constants */
  233. /* Address spaces (FC0-FC2) */
  234. #ifndef USER_DS
  235. #define USER_DS       (1)
  236. #endif
  237. #ifndef KERNEL_DS
  238. #define KERNEL_DS     (5)
  239. #endif
  240.  
  241. #endif /* _M68K_SEGMENT_H */
  242.