1 /* 2 * include/asm-mips/segment.h 3 * 4 * This file is subject to the terms and conditions of the GNU General Public 5 * License. See the file "COPYING" in the main directory of this archive 6 * for more details. 7 * 8 * Copyright (C) 1994, 1995 by Ralf Baechle 9 * 10 * Note that the quad functions are only being used for the 64 bit kernel and 11 * therefore it isn't really important that they will be miscompiled for 12 * 32-bit kernels. 13 */ 14 #ifndef__ASM_MIPS_SEGMENT_H 15 #define__ASM_MIPS_SEGMENT_H 16
17 #ifndef__LANGUAGE_ASSEMBLY__ 18 /* 19 * For memcpy() 20 */ 21 #include <linux/string.h>
22
23 /* 24 * This is a gcc optimization barrier, which essentially 25 * inserts a sequence point in the gcc RTL tree that gcc 26 * can't move code around. This is needed when we enter 27 * or exit a critical region (in this case around user-level 28 * accesses that may sleep, and we can't let gcc optimize 29 * global state around them). 30 */ 31 #define__gcc_barrier() __asm____volatile__("": : :"memory")
32
33 /* 34 * Uh, these should become the main single-value transfer routines.. 35 * They automatically use the right size if we just have the right 36 * pointer type.. 37 */ 38 #defineput_user(x,ptr) __put_user((unsignedlong)(x),(ptr),sizeof(*(ptr)))
39 #defineget_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr))))
40
41 /* 42 * This is a silly but good way to make sure that 43 * the __put_user function is indeed always optimized, 44 * and that we use the correct sizes.. 45 */ 46 externintbad_user_access_length(void);
47
48 /* I should make this use unaligned transfers etc.. */ 49 staticinlinevoid__put_user(unsignedlongx, void * y, intsize)
/* */ 50 { 51 __gcc_barrier();
52 switch (size) { 53 case 1:
54 *(char *) y = x;
55 break;
56 case 2:
57 *(short *) y = x;
58 break;
59 case 4:
60 *(int *) y = x;
61 break;
62 case 8:
63 *(long *) y = x;
64 break;
65 default:
66 bad_user_access_length();
67 } 68 __gcc_barrier();
69 } 70
71 /* I should make this use unaligned transfers etc.. */ 72 staticinlineunsignedlong__get_user(constvoid * y, intsize)
/* */ 73 { 74 unsignedlongresult;
75
76 __gcc_barrier();
77 switch (size) { 78 case 1:
79 result = *(unsignedchar *) y;
80 break;
81 case 2:
82 result = *(unsignedshort *) y;
83 break;
84 case 4:
85 result = *(unsignedint *) y;
86 break;
87 case 8:
88 result = *(unsignedlong *) y;
89 break;
90 default:
91 result = bad_user_access_length();
92 break;
93 } 94 __gcc_barrier();
95
96 returnresult;
97 } 98
99 #defineget_fs_byte(addr) get_user((unsignedchar *)(addr))
100 #defineget_fs_word(addr) get_user((unsignedshort *)(addr))
101 #defineget_fs_long(addr) get_user((unsignedint *)(addr))
102 #defineget_fs_quad(addr) get_user((unsignedlong *)(addr))
103
104 #defineput_fs_byte(x,addr) put_user((x),(char *)(addr))
105 #defineput_fs_word(x,addr) put_user((x),(short *)(addr))
106 #defineput_fs_long(x,addr) put_user((x),(int *)(addr))
107 #defineput_fs_quad(x,addr) put_user((x),(long *)(addr))
108
109 staticinlinevoidmemcpy_fromfs(void * to, constvoid * from, unsignedlongn)
/* */ 110 { 111 __gcc_barrier();
112 memcpy(to, from, n);
113 __gcc_barrier();
114 } 115
116 staticinlinevoidmemcpy_tofs(void * to, constvoid * from, unsignedlongn)
/* */ 117 { 118 __gcc_barrier();
119 memcpy(to, from, n);
120 __gcc_barrier();
121 } 122
123 /* 124 * For segmented architectures, these are used to specify which segment 125 * to use for the above functions. 126 * 127 * MIPS is not segmented, so these are just dummies. 128 */ 129
130 #defineKERNEL_DS 0
131 #defineUSER_DS 1
132
133 staticinlineunsignedlongget_fs(void)
/* */ 134 { 135 returnUSER_DS;
136 } 137
138 staticinlineunsignedlongget_ds(void)
/* */ 139 { 140 returnKERNEL_DS;
141 } 142
143 staticinlinevoidset_fs(unsignedlongval)
/* */ 144 { 145 } 146
147 #endif/* !__LANGUAGE_ASSEMBLY__ */ 148
149 /* 150 * Memory segments (32bit kernel mode addresses) 151 */ 152 #define KUSEG 0x00000000
153 #defineKSEG0 0x80000000
154 #defineKSEG1 0xa0000000
155 #defineKSEG2 0xc0000000
156 #defineKSEG3 0xe0000000
157
158 /* 159 * Returns the kernel segment base of a given address 160 */ 161 #defineKSEGX(a) (((unsignedlong)(a)) & 0xe0000000)
162
163 /* 164 * Returns the physical address of a KSEG0/KSEG1 address 165 */ 166 #definePHYSADDR(a) (((unsignedlong)(a)) & 0x1fffffff)
167
168 /* 169 * Map an address to a certain kernel segment 170 */ 171 #defineKSEG0ADDR(a) ((((unsignedlong)(a)) & 0x1fffffff) | KSEG0)
172 #defineKSEG1ADDR(a) ((((unsignedlong)(a)) & 0x1fffffff) | KSEG1)
173 #define KSEG2ADDR(a) ((((unsignedlong)(a)) & 0x1fffffff) | KSEG2)
174 #define KSEG3ADDR(a) ((((unsignedlong)(a)) & 0x1fffffff) | KSEG3)
175
176 /* 177 * Memory segments (64bit kernel mode addresses) 178 */ 179 #define XKUSEG 0x0000 0000 0000 0000
180 #define XKSSEG 0x4000 0000 0000 0000
181 #define XKPHYS 0x8000 0000 0000 0000
182 #define XKSEG 0xc000 0000 0000 0000
183 #define CKSEG0 0xffff ffff 8000 0000
184 #define CKSEG1 0xffff ffff a000 0000
185 #define CKSSEG 0xffff ffff c000 0000
186 #define CKSEG3 0xffff ffff e000 0000
187
188 #endif/* __ASM_MIPS_SEGMENT_H */