Annotation of sys/arch/amd64/amd64/copy.S, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: copy.S,v 1.3 2007/05/29 23:03:20 tom Exp $ */
2: /* $NetBSD: copy.S,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */
3:
4: /*
5: * Copyright (c) 2001 Wasabi Systems, Inc.
6: * All rights reserved.
7: *
8: * Written by Frank van der Linden for Wasabi Systems, Inc.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed for the NetBSD Project by
21: * Wasabi Systems, Inc.
22: * 4. The name of Wasabi Systems, Inc. may not be used to endorse
23: * or promote products derived from this software without specific prior
24: * written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
30: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36: * POSSIBILITY OF SUCH DAMAGE.
37: */
38:
39: #include "assym.h"
40:
41: #include <sys/errno.h>
42: #include <sys/syscall.h>
43:
44: #include <machine/asm.h>
45:
46: /*
47: * Copy routines from and to userland, plus a few more. See the
48: * section 9 manpages for info. Some cases can be optimized more.
49: *
50: * I wonder if it's worthwhile to make these use SSE2 registers.
51: */
52:
53: /*
54: * XXXfvdl appears only to be used by pccons.
55: *
56: * fillw(short pattern, caddr_t addr, size_t len);
57: * Write len copies of pattern at addr.
58: * appears to be used by pccons.
59: */
60: ENTRY(fillw)
61: movl %edi,%eax
62: movq %rsi,%rdi
63: movw %ax,%cx
64: rorl $16,%eax
65: movw %cx,%ax
66: cld
67: movq %rdx,%rcx
68: shrq %rcx
69: rep
70: stosl
71: movq %rdx,%rcx
72: andq $1,%rcx
73: rep
74: stosw
75: ret
76:
77: ENTRY(kcopy)
78: movq CPUVAR(CURPCB),%rax
79: pushq PCB_ONFAULT(%rax)
80: leaq _C_LABEL(copy_fault)(%rip),%r11
81: movq %r11, PCB_ONFAULT(%rax)
82:
83: xchgq %rdi,%rsi
84: movq %rdx,%rcx
85:
86: movq %rdi,%rax
87: subq %rsi,%rax
88: cmpq %rcx,%rax # overlapping?
89: jb 1f
90: cld # nope, copy forward
91: shrq $3,%rcx # copy by 64-bit words
92: rep
93: movsq
94:
95: movq %rdx,%rcx
96: andl $7,%ecx # any bytes left?
97: rep
98: movsb
99:
100: movq CPUVAR(CURPCB),%rdx
101: popq PCB_ONFAULT(%rdx)
102: xorq %rax,%rax
103: ret
104:
105: 1: addq %rcx,%rdi # copy backward
106: addq %rcx,%rsi
107: std
108: andq $7,%rcx # any fractional bytes?
109: decq %rdi
110: decq %rsi
111: rep
112: movsb
113: movq %rdx,%rcx # copy remainder by 64-bit words
114: shrq $3,%rcx
115: subq $7,%rsi
116: subq $7,%rdi
117: rep
118: movsq
119: cld
120:
121: movq CPUVAR(CURPCB),%rdx
122: popq PCB_ONFAULT(%rdx)
123: xorq %rax,%rax
124: ret
125:
126: ENTRY(copyout)
127: pushq $0
128:
129: xchgq %rdi,%rsi
130: movq %rdx,%rax
131:
132: movq %rdi,%rdx
133: addq %rax,%rdx
134: jc _C_LABEL(copy_efault)
135: movq $VM_MAXUSER_ADDRESS,%r8
136: cmpq %r8,%rdx
137: ja _C_LABEL(copy_efault)
138:
139: movq CPUVAR(CURPCB),%rdx
140: leaq _C_LABEL(copy_fault)(%rip),%r11
141: movq %r11,PCB_ONFAULT(%rdx)
142:
143: cld
144: movq %rax,%rcx
145: shrq $3,%rcx
146: rep
147: movsq
148: movb %al,%cl
149: andb $7,%cl
150: rep
151: movsb
152:
153: popq PCB_ONFAULT(%rdx)
154: xorl %eax,%eax
155: ret
156:
157: ENTRY(copyin)
158: movq CPUVAR(CURPCB),%rax
159: pushq $0
160: leaq _C_LABEL(copy_fault)(%rip),%r11
161: movq %r11,PCB_ONFAULT(%rax)
162:
163: xchgq %rdi,%rsi
164: movq %rdx,%rax
165:
166: movq %rsi,%rdx
167: addq %rax,%rdx
168: jc _C_LABEL(copy_efault)
169: movq $VM_MAXUSER_ADDRESS,%r8
170: cmpq %r8,%rdx
171: ja _C_LABEL(copy_efault)
172:
173: 3: /* bcopy(%rsi, %rdi, %rax); */
174: cld
175: movq %rax,%rcx
176: shrq $3,%rcx
177: rep
178: movsq
179: movb %al,%cl
180: andb $7,%cl
181: rep
182: movsb
183:
184: movq CPUVAR(CURPCB),%rdx
185: popq PCB_ONFAULT(%rdx)
186: xorl %eax,%eax
187: ret
188:
189: NENTRY(copy_efault)
190: movq $EFAULT,%rax
191:
192: NENTRY(copy_fault)
193: movq CPUVAR(CURPCB),%rdx
194: popq PCB_ONFAULT(%rdx)
195: ret
196:
197: ENTRY(copyoutstr)
198: xchgq %rdi,%rsi
199: movq %rdx,%r8
200: movq %rcx,%r9
201:
202: 5: movq CPUVAR(CURPCB),%rax
203: leaq _C_LABEL(copystr_fault)(%rip),%r11
204: movq %r11,PCB_ONFAULT(%rax)
205: /*
206: * Get min(%rdx, VM_MAXUSER_ADDRESS-%rdi).
207: */
208: movq $VM_MAXUSER_ADDRESS,%rax
209: subq %rdi,%rax
210: jbe _C_LABEL(copystr_efault) /* die if CF == 1 || ZF == 1 */
211: cmpq %rdx,%rax
212: jae 1f
213: movq %rax,%rdx
214: movq %rax,%r8
215:
216: 1: incq %rdx
217: cld
218:
219: 1: decq %rdx
220: jz 2f
221: lodsb
222: stosb
223: testb %al,%al
224: jnz 1b
225:
226: /* Success -- 0 byte reached. */
227: decq %rdx
228: xorq %rax,%rax
229: jmp copystr_return
230:
231: 2: /* rdx is zero -- return EFAULT or ENAMETOOLONG. */
232: movq $VM_MAXUSER_ADDRESS,%r11
233: cmpq %r11,%rdi
234: jae _C_LABEL(copystr_efault)
235: movq $ENAMETOOLONG,%rax
236: jmp copystr_return
237:
238: ENTRY(copyinstr)
239: xchgq %rdi,%rsi
240: movq %rdx,%r8
241: movq %rcx,%r9
242:
243: movq CPUVAR(CURPCB),%rcx
244: leaq _C_LABEL(copystr_fault)(%rip),%r11
245: movq %r11,PCB_ONFAULT(%rcx)
246:
247: /*
248: * Get min(%rdx, VM_MAXUSER_ADDRESS-%rsi).
249: */
250: movq $VM_MAXUSER_ADDRESS,%rax
251: subq %rsi,%rax
252: jbe _C_LABEL(copystr_efault) /* die if CF == 1 || ZF == 1 */
253: cmpq %rdx,%rax
254: jae 1f
255: movq %rax,%rdx
256: movq %rax,%r8
257:
258: 1: incq %rdx
259: cld
260:
261: 1: decq %rdx
262: jz 2f
263: lodsb
264: stosb
265: testb %al,%al
266: jnz 1b
267:
268: /* Success -- 0 byte reached. */
269: decq %rdx
270: xorq %rax,%rax
271: jmp copystr_return
272:
273: 2: /* edx is zero -- return EFAULT or ENAMETOOLONG. */
274: movq $VM_MAXUSER_ADDRESS,%r11
275: cmpq %r11,%rsi
276: jae _C_LABEL(copystr_efault)
277: movq $ENAMETOOLONG,%rax
278: jmp copystr_return
279:
280: ENTRY(copystr_efault)
281: movl $EFAULT,%eax
282:
283: ENTRY(copystr_fault)
284: copystr_return:
285: /* Set *lencopied and return %eax. */
286: movq CPUVAR(CURPCB),%rcx
287: movq $0,PCB_ONFAULT(%rcx)
288: testq %r9,%r9
289: jz 8f
290: subq %rdx,%r8
291: movq %r8,(%r9)
292:
293: 8: ret
294:
295: ENTRY(copystr)
296: xchgq %rdi,%rsi
297: movq %rdx,%r8
298:
299: incq %rdx
300: cld
301:
302: 1: decq %rdx
303: jz 4f
304: lodsb
305: stosb
306: testb %al,%al
307: jnz 1b
308:
309: /* Success -- 0 byte reached. */
310: decq %rdx
311: xorl %eax,%eax
312: jmp 6f
313:
314: 4: /* edx is zero -- return ENAMETOOLONG. */
315: movl $ENAMETOOLONG,%eax
316:
317: 6: /* Set *lencopied and return %eax. */
318: testq %rcx,%rcx
319: jz 7f
320: subq %rdx,%r8
321: movq %r8,(%rcx)
322:
323: 7: ret
CVSweb