| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: copy.S,v 1.11 2008/05/30 11:03:29 ad Exp $ */ | | 1 | /* $NetBSD: copy.S,v 1.12 2008/09/18 21:35:17 dsl Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2001 Wasabi Systems, Inc. | | 4 | * Copyright (c) 2001 Wasabi Systems, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Written by Frank van der Linden for Wasabi Systems, Inc. | | 7 | * Written by Frank van der Linden for Wasabi Systems, Inc. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -136,95 +136,98 @@ ENTRY(kcopy) | | | @@ -136,95 +136,98 @@ ENTRY(kcopy) |
136 | rep | | 136 | rep |
137 | movsq | | 137 | movsq |
138 | | | 138 | |
139 | movq %rdx,%rcx | | 139 | movq %rdx,%rcx |
140 | andl $7,%ecx # any bytes left? | | 140 | andl $7,%ecx # any bytes left? |
141 | rep | | 141 | rep |
142 | movsb | | 142 | movsb |
143 | | | 143 | |
144 | GET_CURPCB(%rdx) | | 144 | GET_CURPCB(%rdx) |
145 | popq PCB_ONFAULT(%rdx) | | 145 | popq PCB_ONFAULT(%rdx) |
146 | xorq %rax,%rax | | 146 | xorq %rax,%rax |
147 | ret | | 147 | ret |
148 | | | 148 | |
| | | 149 | # Using 'rep movs' to copy backwards is not as fast as for forwards copies |
| | | 150 | # and ought not be done when the copy doesn't acually overlap. |
| | | 151 | # However kcopy() isn't used any that looks even vaguely used often. |
| | | 152 | # I'm also not sure it is ever asked to do overlapping copies! |
| | | 153 | |
149 | 1: addq %rcx,%rdi # copy backward | | 154 | 1: addq %rcx,%rdi # copy backward |
150 | addq %rcx,%rsi | | 155 | addq %rcx,%rsi |
151 | std | | 156 | std |
152 | andq $7,%rcx # any fractional bytes? | | 157 | andq $7,%rcx # any fractional bytes? |
153 | decq %rdi | | 158 | decq %rdi |
154 | decq %rsi | | 159 | decq %rsi |
155 | rep | | 160 | rep |
156 | movsb | | 161 | movsb |
157 | movq %rdx,%rcx # copy remainder by 64-bit words | | 162 | movq %rdx,%rcx # copy remainder by 64-bit words |
158 | shrq $3,%rcx | | 163 | shrq $3,%rcx |
159 | subq $7,%rsi | | 164 | subq $7,%rsi |
160 | subq $7,%rdi | | 165 | subq $7,%rdi |
161 | rep | | 166 | rep |
162 | movsq | | 167 | movsq |
163 | cld | | 168 | cld |
164 | | | 169 | |
165 | GET_CURPCB(%rdx) | | 170 | GET_CURPCB(%rdx) |
166 | popq PCB_ONFAULT(%rdx) | | 171 | popq PCB_ONFAULT(%rdx) |
167 | xorq %rax,%rax | | 172 | xorq %rax,%rax |
168 | ret | | 173 | ret |
169 | | | 174 | |
170 | ENTRY(copyout) | | 175 | ENTRY(copyout) |
171 | DEFERRED_SWITCH_CHECK | | 176 | DEFERRED_SWITCH_CHECK |
172 | pushq $0 | | 177 | pushq $0 # Restored to PCB_ONFAULT(%rdx) |
173 | | | 178 | |
174 | xchgq %rdi,%rsi | | 179 | xchgq %rdi,%rsi # kernel address to %rsi, user to %rdi |
175 | movq %rdx,%rax | | 180 | movq %rdx,%rax # save transfer length (bytes) |
176 | | | 181 | |
177 | movq %rdi,%rdx | | 182 | addq %rdi,%rdx # end address to %rdx |
178 | addq %rax,%rdx | | 183 | jc _C_LABEL(copy_efault) # jump if wraps |
179 | jc _C_LABEL(copy_efault) | | | |
180 | movq $VM_MAXUSER_ADDRESS,%r8 | | 184 | movq $VM_MAXUSER_ADDRESS,%r8 |
181 | cmpq %r8,%rdx | | 185 | cmpq %r8,%rdx |
182 | ja _C_LABEL(copy_efault) | | 186 | ja _C_LABEL(copy_efault) # jump if end in kernel space |
183 | | | 187 | |
184 | GET_CURPCB(%rdx) | | 188 | GET_CURPCB(%rdx) |
185 | leaq _C_LABEL(copy_fault)(%rip),%r11 | | 189 | leaq _C_LABEL(copy_fault)(%rip),%r11 |
186 | movq %r11,PCB_ONFAULT(%rdx) | | 190 | movq %r11,PCB_ONFAULT(%rdx) # prime fault handler |
187 | | | 191 | |
188 | movq %rax,%rcx | | 192 | movq %rax,%rcx # length |
189 | shrq $3,%rcx | | 193 | shrq $3,%rcx # count of 8-byte words |
190 | rep | | 194 | rep |
191 | movsq | | 195 | movsq # copy from %rsi to %rdi |
192 | movb %al,%cl | | 196 | movb %al,%cl |
193 | andb $7,%cl | | 197 | andb $7,%cl # remaining number of bytes |
194 | rep | | 198 | rep |
195 | movsb | | 199 | movsb # copy remaining bytes |
196 | | | 200 | |
197 | popq PCB_ONFAULT(%rdx) | | 201 | popq PCB_ONFAULT(%rdx) |
198 | xorl %eax,%eax | | 202 | xorl %eax,%eax |
199 | ret | | 203 | ret |
200 | DEFERRED_SWITCH_CALL | | 204 | DEFERRED_SWITCH_CALL |
201 | | | 205 | |
202 | ENTRY(copyin) | | 206 | ENTRY(copyin) |
203 | DEFERRED_SWITCH_CHECK | | 207 | DEFERRED_SWITCH_CHECK |
204 | GET_CURPCB(%rax) | | 208 | GET_CURPCB(%rax) |
205 | pushq $0 | | 209 | pushq $0 |
206 | leaq _C_LABEL(copy_fault)(%rip),%r11 | | 210 | leaq _C_LABEL(copy_fault)(%rip),%r11 |
207 | movq %r11,PCB_ONFAULT(%rax) | | 211 | movq %r11,PCB_ONFAULT(%rax) |
208 | | | 212 | |
209 | xchgq %rdi,%rsi | | 213 | xchgq %rdi,%rsi |
210 | movq %rdx,%rax | | 214 | movq %rdx,%rax |
211 | | | 215 | |
212 | movq %rsi,%rdx | | 216 | addq %rsi,%rdx # Check source address not wrapped |
213 | addq %rax,%rdx | | | |
214 | jc _C_LABEL(copy_efault) | | 217 | jc _C_LABEL(copy_efault) |
215 | movq $VM_MAXUSER_ADDRESS,%r8 | | 218 | movq $VM_MAXUSER_ADDRESS,%r8 |
216 | cmpq %r8,%rdx | | 219 | cmpq %r8,%rdx |
217 | ja _C_LABEL(copy_efault) | | 220 | ja _C_LABEL(copy_efault) # j if end in kernel space |
218 | | | 221 | |
219 | 3: /* bcopy(%rsi, %rdi, %rax); */ | | 222 | 3: /* bcopy(%rsi, %rdi, %rax); */ |
220 | movq %rax,%rcx | | 223 | movq %rax,%rcx |
221 | shrq $3,%rcx | | 224 | shrq $3,%rcx |
222 | rep | | 225 | rep |
223 | movsq | | 226 | movsq |
224 | movb %al,%cl | | 227 | movb %al,%cl |
225 | andb $7,%cl | | 228 | andb $7,%cl |
226 | rep | | 229 | rep |
227 | movsb | | 230 | movsb |
228 | | | 231 | |
229 | GET_CURPCB(%rdx) | | 232 | GET_CURPCB(%rdx) |
230 | popq PCB_ONFAULT(%rdx) | | 233 | popq PCB_ONFAULT(%rdx) |