]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i386/i386/support.s
Import libxo-0.9.0:
[FreeBSD/FreeBSD.git] / sys / i386 / i386 / support.s
1 /*-
2  * Copyright (c) 1993 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31
32 #include <machine/asmacros.h>
33 #include <machine/cputypes.h>
34 #include <machine/pmap.h>
35 #include <machine/specialreg.h>
36
37 #include "assym.inc"
38
39 #define IDXSHIFT        10
40
41         .text
42
43 /*
44  * bcopy family
45  * void bzero(void *buf, u_int len)
46  */
47 ENTRY(bzero)
48         pushl   %edi
49         movl    8(%esp),%edi
50         movl    12(%esp),%ecx
51         xorl    %eax,%eax
52         shrl    $2,%ecx
53         rep
54         stosl
55         movl    12(%esp),%ecx
56         andl    $3,%ecx
57         rep
58         stosb
59         popl    %edi
60         ret
61 END(bzero)
62
63 ENTRY(sse2_pagezero)
64         pushl   %ebx
65         movl    8(%esp),%ecx
66         movl    %ecx,%eax
67         addl    $4096,%eax
68         xor     %ebx,%ebx
69         jmp     1f
70         /*
71          * The loop takes 14 bytes.  Ensure that it doesn't cross a 16-byte
72          * cache line.
73          */
74         .p2align 4,0x90
75 1:
76         movnti  %ebx,(%ecx)
77         movnti  %ebx,4(%ecx)
78         addl    $8,%ecx
79         cmpl    %ecx,%eax
80         jne     1b
81         sfence
82         popl    %ebx
83         ret
84 END(sse2_pagezero)
85
86 ENTRY(i686_pagezero)
87         pushl   %edi
88         pushl   %ebx
89
90         movl    12(%esp),%edi
91         movl    $1024,%ecx
92
93         ALIGN_TEXT
94 1:
95         xorl    %eax,%eax
96         repe
97         scasl
98         jnz     2f
99
100         popl    %ebx
101         popl    %edi
102         ret
103
104         ALIGN_TEXT
105
106 2:
107         incl    %ecx
108         subl    $4,%edi
109
110         movl    %ecx,%edx
111         cmpl    $16,%ecx
112
113         jge     3f
114
115         movl    %edi,%ebx
116         andl    $0x3f,%ebx
117         shrl    %ebx
118         shrl    %ebx
119         movl    $16,%ecx
120         subl    %ebx,%ecx
121
122 3:
123         subl    %ecx,%edx
124         rep
125         stosl
126
127         movl    %edx,%ecx
128         testl   %edx,%edx
129         jnz     1b
130
131         popl    %ebx
132         popl    %edi
133         ret
134 END(i686_pagezero)
135
136 /* fillw(pat, base, cnt) */
137 ENTRY(fillw)
138         pushl   %edi
139         movl    8(%esp),%eax
140         movl    12(%esp),%edi
141         movl    16(%esp),%ecx
142         rep
143         stosw
144         popl    %edi
145         ret
146 END(fillw)
147
148 /*
149  * bcopy(src, dst, cnt)
150  *  ws@tools.de     (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
151  */
152 ENTRY(bcopy)
153         pushl   %ebp
154         movl    %esp,%ebp
155         pushl   %esi
156         pushl   %edi
157         movl    8(%ebp),%esi
158         movl    12(%ebp),%edi
159         movl    16(%ebp),%ecx
160
161         movl    %edi,%eax
162         subl    %esi,%eax
163         cmpl    %ecx,%eax                       /* overlapping && src < dst? */
164         jb      1f
165
166         shrl    $2,%ecx                         /* copy by 32-bit words */
167         rep
168         movsl
169         movl    16(%ebp),%ecx
170         andl    $3,%ecx                         /* any bytes left? */
171         rep
172         movsb
173         popl    %edi
174         popl    %esi
175         popl    %ebp
176         ret
177
178         ALIGN_TEXT
179 1:
180         addl    %ecx,%edi                       /* copy backwards */
181         addl    %ecx,%esi
182         decl    %edi
183         decl    %esi
184         andl    $3,%ecx                         /* any fractional bytes? */
185         std
186         rep
187         movsb
188         movl    16(%ebp),%ecx                   /* copy remainder by 32-bit words */
189         shrl    $2,%ecx
190         subl    $3,%esi
191         subl    $3,%edi
192         rep
193         movsl
194         popl    %edi
195         popl    %esi
196         cld
197         popl    %ebp
198         ret
199 END(bcopy)
200
201 /*
202  * Note: memcpy does not support overlapping copies
203  */
204 ENTRY(memcpy)
205         pushl   %edi
206         pushl   %esi
207         movl    12(%esp),%edi
208         movl    16(%esp),%esi
209         movl    20(%esp),%ecx
210         movl    %edi,%eax
211         shrl    $2,%ecx                         /* copy by 32-bit words */
212         rep
213         movsl
214         movl    20(%esp),%ecx
215         andl    $3,%ecx                         /* any bytes left? */
216         rep
217         movsb
218         popl    %esi
219         popl    %edi
220         ret
221 END(memcpy)
222
223 /*
224  * copystr(from, to, maxlen, int *lencopied) - MP SAFE
225  */
226 ENTRY(copystr)
227         pushl   %esi
228         pushl   %edi
229
230         movl    12(%esp),%esi                   /* %esi = from */
231         movl    16(%esp),%edi                   /* %edi = to */
232         movl    20(%esp),%edx                   /* %edx = maxlen */
233         incl    %edx
234 1:
235         decl    %edx
236         jz      4f
237         lodsb
238         stosb
239         orb     %al,%al
240         jnz     1b
241
242         /* Success -- 0 byte reached */
243         decl    %edx
244         xorl    %eax,%eax
245         jmp     6f
246 4:
247         /* edx is zero -- return ENAMETOOLONG */
248         movl    $ENAMETOOLONG,%eax
249
250 6:
251         /* set *lencopied and return %eax */
252         movl    20(%esp),%ecx
253         subl    %edx,%ecx
254         movl    24(%esp),%edx
255         testl   %edx,%edx
256         jz      7f
257         movl    %ecx,(%edx)
258 7:
259         popl    %edi
260         popl    %esi
261         ret
262 END(copystr)
263
264 ENTRY(bcmp)
265         pushl   %edi
266         pushl   %esi
267         movl    12(%esp),%edi
268         movl    16(%esp),%esi
269         movl    20(%esp),%edx
270
271         movl    %edx,%ecx
272         shrl    $2,%ecx
273         repe
274         cmpsl
275         jne     1f
276
277         movl    %edx,%ecx
278         andl    $3,%ecx
279         repe
280         cmpsb
281 1:
282         setne   %al
283         movsbl  %al,%eax
284         popl    %esi
285         popl    %edi
286         ret
287 END(bcmp)
288
289 /*
290  * Handling of special 386 registers and descriptor tables etc
291  */
292 /* void lgdt(struct region_descriptor *rdp); */
293 ENTRY(lgdt)
294         /* reload the descriptor table */
295         movl    4(%esp),%eax
296         lgdt    (%eax)
297
298         /* flush the prefetch q */
299         jmp     1f
300         nop
301 1:
302         /* reload "stale" selectors */
303         movl    $KDSEL,%eax
304         movl    %eax,%ds
305         movl    %eax,%es
306         movl    %eax,%gs
307         movl    %eax,%ss
308         movl    $KPSEL,%eax
309         movl    %eax,%fs
310
311         /* reload code selector by turning return into intersegmental return */
312         movl    (%esp),%eax
313         pushl   %eax
314         movl    $KCSEL,4(%esp)
315         MEXITCOUNT
316         lret
317 END(lgdt)
318
319 /* ssdtosd(*ssdp,*sdp) */
320 ENTRY(ssdtosd)
321         pushl   %ebx
322         movl    8(%esp),%ecx
323         movl    8(%ecx),%ebx
324         shll    $16,%ebx
325         movl    (%ecx),%edx
326         roll    $16,%edx
327         movb    %dh,%bl
328         movb    %dl,%bh
329         rorl    $8,%ebx
330         movl    4(%ecx),%eax
331         movw    %ax,%dx
332         andl    $0xf0000,%eax
333         orl     %eax,%ebx
334         movl    12(%esp),%ecx
335         movl    %edx,(%ecx)
336         movl    %ebx,4(%ecx)
337         popl    %ebx
338         ret
339 END(ssdtosd)
340
341 /* void reset_dbregs() */
342 ENTRY(reset_dbregs)
343         movl    $0,%eax
344         movl    %eax,%dr7       /* disable all breakpoints first */
345         movl    %eax,%dr0
346         movl    %eax,%dr1
347         movl    %eax,%dr2
348         movl    %eax,%dr3
349         movl    %eax,%dr6
350         ret
351 END(reset_dbregs)
352
353 /*****************************************************************************/
354 /* setjump, longjump                                                         */
355 /*****************************************************************************/
356
357 ENTRY(setjmp)
358         movl    4(%esp),%eax
359         movl    %ebx,(%eax)                     /* save ebx */
360         movl    %esp,4(%eax)                    /* save esp */
361         movl    %ebp,8(%eax)                    /* save ebp */
362         movl    %esi,12(%eax)                   /* save esi */
363         movl    %edi,16(%eax)                   /* save edi */
364         movl    (%esp),%edx                     /* get rta */
365         movl    %edx,20(%eax)                   /* save eip */
366         xorl    %eax,%eax                       /* return(0); */
367         ret
368 END(setjmp)
369
370 ENTRY(longjmp)
371         movl    4(%esp),%eax
372         movl    (%eax),%ebx                     /* restore ebx */
373         movl    4(%eax),%esp                    /* restore esp */
374         movl    8(%eax),%ebp                    /* restore ebp */
375         movl    12(%eax),%esi                   /* restore esi */
376         movl    16(%eax),%edi                   /* restore edi */
377         movl    20(%eax),%edx                   /* get rta */
378         movl    %edx,(%esp)                     /* put in return frame */
379         xorl    %eax,%eax                       /* return(1); */
380         incl    %eax
381         ret
382 END(longjmp)
383
384 /*
385  * Support for reading MSRs in the safe manner.  (Instead of panic on #gp,
386  * return an error.)
387  */
388 ENTRY(rdmsr_safe)
389 /* int rdmsr_safe(u_int msr, uint64_t *data) */
390         movl    PCPU(CURPCB),%ecx
391         movl    $msr_onfault,PCB_ONFAULT(%ecx)
392
393         movl    4(%esp),%ecx
394         rdmsr
395         movl    8(%esp),%ecx
396         movl    %eax,(%ecx)
397         movl    %edx,4(%ecx)
398         xorl    %eax,%eax
399
400         movl    PCPU(CURPCB),%ecx
401         movl    %eax,PCB_ONFAULT(%ecx)
402
403         ret
404
405 /*
406  * Support for writing MSRs in the safe manner.  (Instead of panic on #gp,
407  * return an error.)
408  */
409 ENTRY(wrmsr_safe)
410 /* int wrmsr_safe(u_int msr, uint64_t data) */
411         movl    PCPU(CURPCB),%ecx
412         movl    $msr_onfault,PCB_ONFAULT(%ecx)
413
414         movl    4(%esp),%ecx
415         movl    8(%esp),%eax
416         movl    12(%esp),%edx
417         wrmsr
418         xorl    %eax,%eax
419
420         movl    PCPU(CURPCB),%ecx
421         movl    %eax,PCB_ONFAULT(%ecx)
422
423         ret
424
425 /*
426  * MSR operations fault handler
427  */
428         ALIGN_TEXT
429 msr_onfault:
430         movl    PCPU(CURPCB),%ecx
431         movl    $0,PCB_ONFAULT(%ecx)
432         movl    $EFAULT,%eax
433         ret
434
435 ENTRY(handle_ibrs_entry)
436         ret
437 END(handle_ibrs_entry)
438
439 ENTRY(handle_ibrs_exit)
440         ret
441 END(handle_ibrs_exit)