]> git.buserror.net Git - polintos/scott/priv.git/blob - kernel/include/arch-x86/usercopy.h
update
[polintos/scott/priv.git] / kernel / include / arch-x86 / usercopy.h
1 #ifndef _ARCH_USERCOPY_H
2 #define _ARCH_USERCOPY_H
3
4 #include <kern/types.h>
5 #include <kern/libc.h>
6
7 namespace Arch {
8         template <typename T>
9         static inline void copyin(T *uptr, T *kdata, int count)
10         {
11                 // OPT: use alignof for movsw and movsl versions
12                 ulong bytes = sizeof(*kdata) * count;
13                 int cause;
14                 
15                 if ((ulong)uptr + bytes >= PHYSMEM_START ||
16                     (ulong)uptr + bytes < (ulong)uptr) {
17                         cause = 1;
18                         goto bad;
19                 }
20                 
21                 asm("1: rep; movsb\n"
22                     "2:\n"
23                     ".section .extable,\"a\"\n"
24                     ".align 4\n"
25                     ".long 1b\n"
26                     ".long 2b\n"
27                     ".previous\n" : "+c" (bytes), "+D" (kdata), "+S" (uptr), "=d" (cause));
28         
29                 if (bytes != 0) {
30                 bad:
31                         throw_idl(MemoryFault, reinterpret_cast<ulong>(uptr),
32                                   0, NULL, NULL, cause);
33                 }
34         }
35
36         template <typename T>
37         static inline void copyin(T *uptr, T &kdata)
38         {
39                 // OPT: special versions for common small sizes
40                 copyin(uptr, &kdata, 1);
41         }
42         
43         template <typename T>
44         static inline T copyin(T *uptr)
45         {
46                 T kdata;
47                 copyin(uptr, kdata);
48                 return kdata;
49         }
50
51         template <typename T>
52         static inline void copyout(T *uptr, T *kdata, int count)
53         {
54                 // OPT: use alignof for movsw and movsl versions
55                 ulong bytes = sizeof(*kdata) * count;
56                 int cause;
57
58                 if ((ulong)uptr + bytes >= PHYSMEM_START ||
59                     (ulong)uptr + bytes < (ulong)uptr) {
60                         cause = 1;
61                         goto bad;
62                 }
63                 
64                 asm("1: rep; movsb\n"
65                     "2:\n"
66                     ".section .extable,\"a\"\n"
67                     ".long 1b\n"
68                     ".long 2b\n"
69                     ".previous\n" : "+c" (bytes), "+S" (kdata), "+D" (uptr), "=d" (cause));
70         
71                 if (bytes != 0) {
72                 bad:
73                         throw_idl(MemoryFault, reinterpret_cast<ulong>(uptr),
74                                   0, NULL, NULL, cause);
75                 }
76         }
77
78         template <typename T>
79         static inline void copyout(T *uptr, T &kdata)
80         {
81                 copyout(uptr, &kdata, sizeof(kdata));
82         }
83 }
84
85 #endif