kernel: Make SMP support default (and non-optional).
[dragonfly.git] / sys / platform / pc32 / i386 / support.s
CommitLineData
984263bc
MD
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. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * $FreeBSD: src/sys/i386/i386/support.s,v 1.67.2.5 2001/08/15 01:23:50 peter Exp $
34 */
35
984263bc
MD
36#include <machine/asmacros.h>
37#include <machine/cputypes.h>
38#include <machine/pmap.h>
39#include <machine/specialreg.h>
40
41#include "assym.s"
42
43#define IDXSHIFT 10
44
45 .data
263541db
MD
46
47 .globl memcpy_vector
48memcpy_vector:
49 .long asm_generic_memcpy
50
2954c92f
MD
51 .globl bcopy_vector
52bcopy_vector:
263541db
MD
53 .long asm_generic_bcopy
54
2954c92f
MD
55 .globl ovbcopy_vector
56ovbcopy_vector:
263541db 57 .long asm_generic_bcopy
984263bc
MD
58
59 .text
60
984263bc
MD
61/* fillw(pat, base, cnt) */
62ENTRY(fillw)
63 pushl %edi
64 movl 8(%esp),%eax
65 movl 12(%esp),%edi
66 movl 16(%esp),%ecx
67 cld
68 rep
69 stosw
70 popl %edi
71 ret
72
263541db
MD
73/*
74 * void bcopy(const void *s, void *d, size_t count)
75 *
76 * Normal bcopy() vector, an optimized bcopy may be installed in
77 * bcopy_vector.
78 */
79ENTRY(bcopy)
984263bc
MD
80 pushl %esi
81 pushl %edi
263541db
MD
82 movl 4+8(%esp),%esi /* caddr_t from */
83 movl 8+8(%esp),%edi /* caddr_t to */
84 movl 12+8(%esp),%ecx /* size_t len */
85 call *bcopy_vector
984263bc
MD
86 popl %edi
87 popl %esi
984263bc
MD
88 ret
89
984263bc 90/*
263541db 91 * Generic (integer-only) bcopy() vector.
984263bc
MD
92 */
93ENTRY(generic_bcopy)
94 pushl %esi
95 pushl %edi
263541db
MD
96 movl 4+8(%esp),%esi /* caddr_t from */
97 movl 8+8(%esp),%edi /* caddr_t to */
98 movl 12+8(%esp),%ecx /* size_t len */
99 call asm_generic_bcopy
984263bc
MD
100 popl %edi
101 popl %esi
102 ret
103
263541db 104ENTRY(ovbcopy)
984263bc
MD
105 pushl %esi
106 pushl %edi
263541db
MD
107 movl 4+8(%esp),%esi /* caddr_t from */
108 movl 8+8(%esp),%edi /* caddr_t to */
109 movl 12+8(%esp),%ecx /* size_t len */
110 call *ovbcopy_vector
984263bc
MD
111 popl %edi
112 popl %esi
113 ret
114
984263bc 115/*
263541db
MD
116 * void *memcpy(void *d, const void *s, size_t count)
117 *
118 * Note: memcpy does not have to support overlapping copies.
119 *
120 * Note: (d, s) arguments reversed from bcopy, and memcpy() returns d
121 * while bcopy() returns void.
984263bc
MD
122 */
123ENTRY(memcpy)
984263bc 124 pushl %esi
263541db
MD
125 pushl %edi
126 movl 4+8(%esp),%edi
127 movl 8+8(%esp),%esi
128 movl 12+8(%esp),%ecx
129 call *memcpy_vector
130 movl 4+8(%esp),%eax
984263bc 131 popl %edi
263541db 132 popl %esi
984263bc
MD
133 ret
134
263541db
MD
135/*
136 * A stack-based on-fault routine is used for more complex PCB_ONFAULT
137 * situations (such as memcpy/bcopy/bzero). In this case the on-fault
138 * routine must be pushed on the stack.
139 */
140stack_onfault:
141 ret
984263bc
MD
142
143/*****************************************************************************/
144/* copyout and fubyte family */
145/*****************************************************************************/
146/*
147 * Access user memory from inside the kernel. These routines and possibly
148 * the math- and DOS emulators should be the only places that do this.
149 *
150 * We have to access the memory with user's permissions, so use a segment
151 * selector with RPL 3. For writes to user space we have to additionally
152 * check the PTE for write permission, because the 386 does not check
153 * write permissions when we are executing with EPL 0. The 486 does check
154 * this if the WP bit is set in CR0, so we can use a simpler version here.
155 *
156 * These routines set curpcb->onfault for the time they execute. When a
157 * protection violation occurs inside the functions, the trap handler
158 * returns to *curpcb->onfault instead of the function.
159 */
160
161/*
4db955e1 162 * copyout(from_kernel, to_user, len) - MP SAFE
984263bc
MD
163 */
164ENTRY(copyout)
2954c92f 165 movl PCPU(curthread),%eax
b7c628e4 166 movl TD_PCB(%eax),%eax
984263bc
MD
167 pushl %esi
168 pushl %edi
169 pushl %ebx
3961a39d 170 pushl $copyout_fault2
263541db 171 movl $stack_onfault,PCB_ONFAULT(%eax)
93ad6da2
MD
172 movl %esp,PCB_ONFAULT_SP(%eax)
173 subl $12,PCB_ONFAULT_SP(%eax) /* call,ebx,stackedfault */
174 /* for *memcpy_vector */
263541db
MD
175 movl 4+16(%esp),%esi
176 movl 8+16(%esp),%edi
177 movl 12+16(%esp),%ebx
984263bc
MD
178 testl %ebx,%ebx /* anything to do? */
179 jz done_copyout
180
181 /*
182 * Check explicitly for non-user addresses. If 486 write protection
183 * is being used, this check is essential because we are in kernel
184 * mode so the h/w does not provide any protection against writing
185 * kernel addresses.
186 */
187
188 /*
189 * First, prevent address wrapping.
190 */
191 movl %edi,%eax
192 addl %ebx,%eax
3961a39d 193 jc copyout_fault1
984263bc 194/*
88181b08 195 * XXX STOP USING VM_MAX_USER_ADDRESS.
984263bc
MD
196 * It is an end address, not a max, so every time it is used correctly it
197 * looks like there is an off by one error, and of course it caused an off
198 * by one error in several places.
199 */
88181b08 200 cmpl $VM_MAX_USER_ADDRESS,%eax
3961a39d 201 ja copyout_fault1
984263bc 202
263541db 203 /*
c885c20e 204 * Convert copyout to memcpy_vector(dest:%edi, src:%esi, count:%ecx)
263541db 205 */
984263bc 206 movl %ebx,%ecx
263541db 207 call *memcpy_vector
984263bc
MD
208
209done_copyout:
263541db
MD
210 /*
211 * non-error return
212 */
213 addl $4,%esp
214 movl PCPU(curthread),%edx
215 xorl %eax,%eax
216 movl TD_PCB(%edx),%edx
984263bc
MD
217 popl %ebx
218 popl %edi
219 popl %esi
984263bc
MD
220 movl %eax,PCB_ONFAULT(%edx)
221 ret
222
223 ALIGN_TEXT
3961a39d
MD
224copyout_fault1:
225 addl $4,%esp /* skip pushed copyout_fault vector */
226copyout_fault2:
984263bc
MD
227 popl %ebx
228 popl %edi
229 popl %esi
2954c92f 230 movl PCPU(curthread),%edx
b7c628e4 231 movl TD_PCB(%edx),%edx
984263bc
MD
232 movl $0,PCB_ONFAULT(%edx)
233 movl $EFAULT,%eax
234 ret
235
984263bc
MD
236/*
237 * copyin(from_user, to_kernel, len) - MP SAFE
238 */
984263bc 239
263541db 240ENTRY(copyin)
2954c92f 241 movl PCPU(curthread),%eax
b7c628e4 242 movl TD_PCB(%eax),%eax
984263bc
MD
243 pushl %esi
244 pushl %edi
3961a39d 245 pushl $copyin_fault2
263541db 246 movl $stack_onfault,PCB_ONFAULT(%eax)
93ad6da2
MD
247 movl %esp,PCB_ONFAULT_SP(%eax)
248 subl $12,PCB_ONFAULT_SP(%eax) /* call,ebx,stackedfault */
249 /* for *memcpy_vector */
263541db
MD
250 movl 4+12(%esp),%esi /* caddr_t from */
251 movl 8+12(%esp),%edi /* caddr_t to */
252 movl 12+12(%esp),%ecx /* size_t len */
984263bc
MD
253
254 /*
255 * make sure address is valid
256 */
257 movl %esi,%edx
258 addl %ecx,%edx
3961a39d 259 jc copyin_fault1
88181b08 260 cmpl $VM_MAX_USER_ADDRESS,%edx
3961a39d 261 ja copyin_fault1
984263bc 262
263541db
MD
263 /*
264 * Call memcpy(destination:%edi, source:%esi, bytes:%ecx)
265 */
266 call *memcpy_vector
984263bc 267
263541db
MD
268 /*
269 * return 0 (no error)
270 */
271 addl $4,%esp
2954c92f 272 movl PCPU(curthread),%edx
263541db 273 xorl %eax,%eax
b7c628e4 274 movl TD_PCB(%edx),%edx
984263bc
MD
275 popl %edi
276 popl %esi
263541db 277 movl %eax,PCB_ONFAULT(%edx)
984263bc
MD
278 ret
279
984263bc 280 /*
263541db 281 * return EFAULT
984263bc 282 */
984263bc 283 ALIGN_TEXT
3961a39d
MD
284copyin_fault1:
285 addl $4,%esp /* skip pushed copyin_fault vector */
286copyin_fault2:
984263bc
MD
287 popl %edi
288 popl %esi
2954c92f 289 movl PCPU(curthread),%edx
b7c628e4 290 movl TD_PCB(%edx),%edx
984263bc
MD
291 movl $0,PCB_ONFAULT(%edx)
292 movl $EFAULT,%eax
293 ret
984263bc 294
8ba5f7ef
AH
295/*
296 * casuword. Compare and set user word. Returns -1 or the current value.
297 */
298
299ENTRY(casuword)
300 movl PCPU(curthread),%ecx
301 movl TD_PCB(%ecx),%ecx
302 movl $fusufault,PCB_ONFAULT(%ecx)
93ad6da2 303 movl %esp,PCB_ONFAULT_SP(%ecx)
8ba5f7ef
AH
304 movl 4(%esp),%edx /* dst */
305 movl 8(%esp),%eax /* old */
306 movl 12(%esp),%ecx /* new */
307
308 cmpl $VM_MAX_USER_ADDRESS-4,%edx /* verify address is valid */
309 ja fusufault
310
8ba5f7ef 311 lock
8ba5f7ef
AH
312 cmpxchgl %ecx,(%edx) /* Compare and set. */
313
314 /*
315 * The old value is in %eax. If the store succeeded it will be the
316 * value we expected (old) from before the store, otherwise it will
317 * be the current value.
318 */
319
320 movl PCPU(curthread),%ecx
321 movl TD_PCB(%ecx),%ecx
8ba5f7ef
AH
322 movl $0,PCB_ONFAULT(%ecx)
323 ret
324END(casuword)
325
984263bc
MD
326/*
327 * fu{byte,sword,word} - MP SAFE
328 *
329 * Fetch a byte (sword, word) from user memory
330 */
331ENTRY(fuword)
2954c92f 332 movl PCPU(curthread),%ecx
b7c628e4 333 movl TD_PCB(%ecx),%ecx
984263bc 334 movl $fusufault,PCB_ONFAULT(%ecx)
93ad6da2 335 movl %esp,PCB_ONFAULT_SP(%ecx)
984263bc
MD
336 movl 4(%esp),%edx /* from */
337
88181b08 338 cmpl $VM_MAX_USER_ADDRESS-4,%edx /* verify address is valid */
984263bc
MD
339 ja fusufault
340
341 movl (%edx),%eax
342 movl $0,PCB_ONFAULT(%ecx)
343 ret
344
984263bc
MD
345/*
346 * fusword - MP SAFE
347 */
348ENTRY(fusword)
2954c92f 349 movl PCPU(curthread),%ecx
b7c628e4 350 movl TD_PCB(%ecx),%ecx
984263bc 351 movl $fusufault,PCB_ONFAULT(%ecx)
93ad6da2 352 movl %esp,PCB_ONFAULT_SP(%ecx)
984263bc
MD
353 movl 4(%esp),%edx
354
88181b08 355 cmpl $VM_MAX_USER_ADDRESS-2,%edx
984263bc
MD
356 ja fusufault
357
358 movzwl (%edx),%eax
359 movl $0,PCB_ONFAULT(%ecx)
360 ret
361
362/*
363 * fubyte - MP SAFE
364 */
365ENTRY(fubyte)
2954c92f 366 movl PCPU(curthread),%ecx
b7c628e4 367 movl TD_PCB(%ecx),%ecx
984263bc 368 movl $fusufault,PCB_ONFAULT(%ecx)
93ad6da2 369 movl %esp,PCB_ONFAULT_SP(%ecx)
984263bc
MD
370 movl 4(%esp),%edx
371
88181b08 372 cmpl $VM_MAX_USER_ADDRESS-1,%edx
984263bc
MD
373 ja fusufault
374
375 movzbl (%edx),%eax
376 movl $0,PCB_ONFAULT(%ecx)
377 ret
378
379 ALIGN_TEXT
380fusufault:
2954c92f 381 movl PCPU(curthread),%ecx
b7c628e4 382 movl TD_PCB(%ecx),%ecx
984263bc
MD
383 xorl %eax,%eax
384 movl %eax,PCB_ONFAULT(%ecx)
385 decl %eax
386 ret
387
388/*
3f938eea 389 * su{byte,sword,word,word32} - MP SAFE
984263bc 390 *
3f938eea 391 * Write a long to user memory
984263bc
MD
392 */
393ENTRY(suword)
2954c92f 394 movl PCPU(curthread),%ecx
b7c628e4 395 movl TD_PCB(%ecx),%ecx
984263bc 396 movl $fusufault,PCB_ONFAULT(%ecx)
93ad6da2 397 movl %esp,PCB_ONFAULT_SP(%ecx)
984263bc
MD
398 movl 4(%esp),%edx
399
88181b08 400 cmpl $VM_MAX_USER_ADDRESS-4,%edx /* verify address validity */
984263bc
MD
401 ja fusufault
402
403 movl 8(%esp),%eax
404 movl %eax,(%edx)
405 xorl %eax,%eax
2954c92f 406 movl PCPU(curthread),%ecx
b7c628e4 407 movl TD_PCB(%ecx),%ecx
984263bc
MD
408 movl %eax,PCB_ONFAULT(%ecx)
409 ret
410
3f938eea
MD
411/*
412 * Write an integer to user memory
413 */
414ENTRY(suword32)
415 movl PCPU(curthread),%ecx
416 movl TD_PCB(%ecx),%ecx
417 movl $fusufault,PCB_ONFAULT(%ecx)
93ad6da2 418 movl %esp,PCB_ONFAULT_SP(%ecx)
3f938eea
MD
419 movl 4(%esp),%edx
420
421 cmpl $VM_MAX_USER_ADDRESS-4,%edx /* verify address validity */
422 ja fusufault
423
424 movl 8(%esp),%eax
425 movl %eax,(%edx)
426 xorl %eax,%eax
427 movl PCPU(curthread),%ecx
428 movl TD_PCB(%ecx),%ecx
429 movl %eax,PCB_ONFAULT(%ecx)
430 ret
431
984263bc 432/*
4db955e1 433 * susword - MP SAFE
984263bc
MD
434 */
435ENTRY(susword)
2954c92f 436 movl PCPU(curthread),%ecx
b7c628e4 437 movl TD_PCB(%ecx),%ecx
984263bc 438 movl $fusufault,PCB_ONFAULT(%ecx)
93ad6da2 439 movl %esp,PCB_ONFAULT_SP(%ecx)
984263bc
MD
440 movl 4(%esp),%edx
441
88181b08 442 cmpl $VM_MAX_USER_ADDRESS-2,%edx /* verify address validity */
984263bc
MD
443 ja fusufault
444
445 movw 8(%esp),%ax
446 movw %ax,(%edx)
447 xorl %eax,%eax
2954c92f 448 movl PCPU(curthread),%ecx /* restore trashed register */
b7c628e4 449 movl TD_PCB(%ecx),%ecx
984263bc
MD
450 movl %eax,PCB_ONFAULT(%ecx)
451 ret
452
453/*
4db955e1 454 * subyte - MP SAFE
984263bc 455 */
984263bc 456ENTRY(subyte)
2954c92f 457 movl PCPU(curthread),%ecx
b7c628e4 458 movl TD_PCB(%ecx),%ecx
984263bc 459 movl $fusufault,PCB_ONFAULT(%ecx)
93ad6da2 460 movl %esp,PCB_ONFAULT_SP(%ecx)
984263bc
MD
461 movl 4(%esp),%edx
462
88181b08 463 cmpl $VM_MAX_USER_ADDRESS-1,%edx /* verify address validity */
984263bc
MD
464 ja fusufault
465
466 movb 8(%esp),%al
467 movb %al,(%edx)
468 xorl %eax,%eax
2954c92f 469 movl PCPU(curthread),%ecx /* restore trashed register */
b7c628e4 470 movl TD_PCB(%ecx),%ecx
984263bc
MD
471 movl %eax,PCB_ONFAULT(%ecx)
472 ret
473
474/*
475 * copyinstr(from, to, maxlen, int *lencopied) - MP SAFE
476 *
477 * copy a string from from to to, stop when a 0 character is reached.
478 * return ENAMETOOLONG if string is longer than maxlen, and
479 * EFAULT on protection violations. If lencopied is non-zero,
480 * return the actual length in *lencopied.
481 */
482ENTRY(copyinstr)
483 pushl %esi
484 pushl %edi
2954c92f 485 movl PCPU(curthread),%ecx
b7c628e4 486 movl TD_PCB(%ecx),%ecx
984263bc 487 movl $cpystrflt,PCB_ONFAULT(%ecx)
93ad6da2 488 movl %esp,PCB_ONFAULT_SP(%ecx)
984263bc
MD
489
490 movl 12(%esp),%esi /* %esi = from */
491 movl 16(%esp),%edi /* %edi = to */
492 movl 20(%esp),%edx /* %edx = maxlen */
493
88181b08 494 movl $VM_MAX_USER_ADDRESS,%eax
984263bc
MD
495
496 /* make sure 'from' is within bounds */
497 subl %esi,%eax
498 jbe cpystrflt
499
88181b08 500 /* restrict maxlen to <= VM_MAX_USER_ADDRESS-from */
984263bc
MD
501 cmpl %edx,%eax
502 jae 1f
503 movl %eax,%edx
504 movl %eax,20(%esp)
5051:
506 incl %edx
507 cld
508
5092:
510 decl %edx
511 jz 3f
512
513 lodsb
514 stosb
515 orb %al,%al
516 jnz 2b
517
518 /* Success -- 0 byte reached */
519 decl %edx
520 xorl %eax,%eax
521 jmp cpystrflt_x
5223:
523 /* edx is zero - return ENAMETOOLONG or EFAULT */
88181b08 524 cmpl $VM_MAX_USER_ADDRESS,%esi
984263bc
MD
525 jae cpystrflt
5264:
527 movl $ENAMETOOLONG,%eax
528 jmp cpystrflt_x
529
530cpystrflt:
531 movl $EFAULT,%eax
532
533cpystrflt_x:
534 /* set *lencopied and return %eax */
2954c92f 535 movl PCPU(curthread),%ecx
b7c628e4 536 movl TD_PCB(%ecx),%ecx
984263bc
MD
537 movl $0,PCB_ONFAULT(%ecx)
538 movl 20(%esp),%ecx
539 subl %edx,%ecx
540 movl 24(%esp),%edx
541 testl %edx,%edx
542 jz 1f
543 movl %ecx,(%edx)
5441:
545 popl %edi
546 popl %esi
547 ret
548
549
550/*
551 * copystr(from, to, maxlen, int *lencopied) - MP SAFE
552 */
553ENTRY(copystr)
554 pushl %esi
555 pushl %edi
556
557 movl 12(%esp),%esi /* %esi = from */
558 movl 16(%esp),%edi /* %edi = to */
559 movl 20(%esp),%edx /* %edx = maxlen */
560 incl %edx
561 cld
5621:
563 decl %edx
564 jz 4f
565 lodsb
566 stosb
567 orb %al,%al
568 jnz 1b
569
570 /* Success -- 0 byte reached */
571 decl %edx
572 xorl %eax,%eax
573 jmp 6f
5744:
575 /* edx is zero -- return ENAMETOOLONG */
576 movl $ENAMETOOLONG,%eax
577
5786:
579 /* set *lencopied and return %eax */
580 movl 20(%esp),%ecx
581 subl %edx,%ecx
582 movl 24(%esp),%edx
583 testl %edx,%edx
584 jz 7f
585 movl %ecx,(%edx)
5867:
587 popl %edi
588 popl %esi
589 ret
590
591ENTRY(bcmp)
592 pushl %edi
593 pushl %esi
594 movl 12(%esp),%edi
595 movl 16(%esp),%esi
596 movl 20(%esp),%edx
597 xorl %eax,%eax
598
599 movl %edx,%ecx
600 shrl $2,%ecx
601 cld /* compare forwards */
602 repe
603 cmpsl
604 jne 1f
605
606 movl %edx,%ecx
607 andl $3,%ecx
608 repe
609 cmpsb
610 je 2f
6111:
612 incl %eax
6132:
614 popl %esi
615 popl %edi
616 ret
617
618
619/*
620 * Handling of special 386 registers and descriptor tables etc
621 */
622/* void lgdt(struct region_descriptor *rdp); */
623ENTRY(lgdt)
624 /* reload the descriptor table */
625 movl 4(%esp),%eax
626 lgdt (%eax)
627
628 /* flush the prefetch q */
629 jmp 1f
630 nop
6311:
632 /* reload "stale" selectors */
633 movl $KDSEL,%eax
634 mov %ax,%ds
635 mov %ax,%es
636 mov %ax,%gs
637 mov %ax,%ss
984263bc 638 movl $KPSEL,%eax
984263bc 639 mov %ax,%fs
4e7c41c5 640 mov %ax,%gs
984263bc
MD
641
642 /* reload code selector by turning return into intersegmental return */
643 movl (%esp),%eax
644 pushl %eax
645 movl $KCSEL,4(%esp)
646 lret
647
648/*
649 * void lidt(struct region_descriptor *rdp);
650 */
651ENTRY(lidt)
652 movl 4(%esp),%eax
653 lidt (%eax)
654 ret
655
656/*
657 * void lldt(u_short sel)
658 */
659ENTRY(lldt)
660 lldt 4(%esp)
661 ret
662
663/*
664 * void ltr(u_short sel)
665 */
666ENTRY(ltr)
667 ltr 4(%esp)
668 ret
669
670/* ssdtosd(*ssdp,*sdp) */
671ENTRY(ssdtosd)
672 pushl %ebx
673 movl 8(%esp),%ecx
674 movl 8(%ecx),%ebx
675 shll $16,%ebx
676 movl (%ecx),%edx
677 roll $16,%edx
678 movb %dh,%bl
679 movb %dl,%bh
680 rorl $8,%ebx
681 movl 4(%ecx),%eax
682 movw %ax,%dx
683 andl $0xf0000,%eax
684 orl %eax,%ebx
685 movl 12(%esp),%ecx
686 movl %edx,(%ecx)
687 movl %ebx,4(%ecx)
688 popl %ebx
689 ret
690
691/* load_cr0(cr0) */
692ENTRY(load_cr0)
693 movl 4(%esp),%eax
694 movl %eax,%cr0
695 ret
696
697/* rcr0() */
698ENTRY(rcr0)
699 movl %cr0,%eax
700 ret
701
702/* rcr3() */
703ENTRY(rcr3)
704 movl %cr3,%eax
705 ret
706
707/* void load_cr3(caddr_t cr3) */
708ENTRY(load_cr3)
709#if defined(SWTCH_OPTIM_STATS)
710 incl _tlb_flush_count
711#endif
712 movl 4(%esp),%eax
713 movl %eax,%cr3
714 ret
715
716/* rcr4() */
717ENTRY(rcr4)
718 movl %cr4,%eax
719 ret
720
721/* void load_cr4(caddr_t cr4) */
722ENTRY(load_cr4)
723 movl 4(%esp),%eax
724 movl %eax,%cr4
725 ret
726
727/* void reset_dbregs() */
728ENTRY(reset_dbregs)
729 movl $0,%eax
730 movl %eax,%dr7 /* disable all breapoints first */
731 movl %eax,%dr0
732 movl %eax,%dr1
733 movl %eax,%dr2
734 movl %eax,%dr3
735 movl %eax,%dr6
736 ret
737
738/*****************************************************************************/
739/* setjump, longjump */
740/*****************************************************************************/
741
742ENTRY(setjmp)
743 movl 4(%esp),%eax
744 movl %ebx,(%eax) /* save ebx */
745 movl %esp,4(%eax) /* save esp */
746 movl %ebp,8(%eax) /* save ebp */
747 movl %esi,12(%eax) /* save esi */
748 movl %edi,16(%eax) /* save edi */
749 movl (%esp),%edx /* get rta */
750 movl %edx,20(%eax) /* save eip */
751 xorl %eax,%eax /* return(0); */
752 ret
753
754ENTRY(longjmp)
755 movl 4(%esp),%eax
756 movl (%eax),%ebx /* restore ebx */
757 movl 4(%eax),%esp /* restore esp */
758 movl 8(%eax),%ebp /* restore ebp */
759 movl 12(%eax),%esi /* restore esi */
760 movl 16(%eax),%edi /* restore edi */
761 movl 20(%eax),%edx /* get rta */
762 movl %edx,(%esp) /* put in return frame */
763 xorl %eax,%eax /* return(1); */
764 incl %eax
765 ret
766
0bdfdda1
SW
767/*
768 * Support for reading MSRs in the safe manner.
769 */
770ENTRY(rdmsr_safe)
771/* int rdmsr_safe(u_int msr, uint64_t *data) */
772 movl PCPU(curthread),%ecx
773 movl TD_PCB(%ecx), %ecx
774 movl $msr_onfault,PCB_ONFAULT(%ecx)
93ad6da2 775 movl %esp,PCB_ONFAULT_SP(%ecx)
0bdfdda1
SW
776
777 movl 4(%esp),%ecx
778 rdmsr
779 movl 8(%esp),%ecx
780 movl %eax,(%ecx)
781 movl %edx,4(%ecx)
782 xorl %eax,%eax
783
784 movl PCPU(curthread),%ecx
785 movl TD_PCB(%ecx), %ecx
786 movl %eax,PCB_ONFAULT(%ecx)
787
788 ret
789
790/*
791 * MSR operations fault handler
792 */
793 ALIGN_TEXT
794msr_onfault:
795 movl PCPU(curthread),%ecx
796 movl TD_PCB(%ecx), %ecx
797 movl $0,PCB_ONFAULT(%ecx)
798 movl $EFAULT,%eax
799 ret
800
984263bc
MD
801/*
802 * Support for BB-profiling (gcc -a). The kernbb program will extract
803 * the data from the kernel.
804 */
805
806 .data
807 ALIGN_DATA
808 .globl bbhead
809bbhead:
810 .long 0
811
812 .text
813NON_GPROF_ENTRY(__bb_init_func)
814 movl 4(%esp),%eax
815 movl $1,(%eax)
816 movl bbhead,%edx
817 movl %edx,16(%eax)
818 movl %eax,bbhead
819 .byte 0xc3 /* avoid macro for `ret' */