support.s revision 12702
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 * $Id: support.s,v 1.24 1995/10/15 18:03:42 phk Exp $ 34 */ 35 36#include "assym.s" /* system definitions */ 37#include "errno.h" /* error return codes */ 38#include "machine/asmacros.h" /* miscellaneous asm macros */ 39#include "machine/cputypes.h" /* types of CPUs */ 40 41#define KDSEL 0x10 /* kernel data selector */ 42#define IDXSHIFT 10 43 44/* 45 * Support for reading real time clock registers 46 */ 47ENTRY(rtcin) /* rtcin(val) */ 48 movl 4(%esp),%eax 49 outb %al,$0x70 50 NOP 51 xorl %eax,%eax 52 inb $0x71,%al 53 NOP 54 ret 55 56/* 57 * bcopy family 58 */ 59 60/* 61 * void bzero(void *base, u_int cnt) 62 * Special code for I486 because stosl uses lots 63 * of clocks. Makes little or no difference on DX2 type 64 * machines, but stosl is about 1/2 as fast as 65 * memory moves on a standard DX !!!!! 66 */ 67ALTENTRY(blkclr) 68ENTRY(bzero) 69#if defined(I486_CPU) 70 cmpl $CPUCLASS_486,_cpu_class 71 jz 1f 72#endif 73 74 pushl %edi 75 movl 8(%esp),%edi 76 movl 12(%esp),%ecx 77 xorl %eax,%eax 78 shrl $2,%ecx 79 cld 80 rep 81 stosl 82 movl 12(%esp),%ecx 83 andl $3,%ecx 84 rep 85 stosb 86 popl %edi 87 ret 88 89#if defined(I486_CPU) 90 SUPERALIGN_TEXT 911: 92 movl 4(%esp),%edx 93 movl 8(%esp),%ecx 94 xorl %eax,%eax 95/ 96/ do 64 byte chunks first 97/ 98/ XXX this is probably over-unrolled at least for DX2's 99/ 1002: 101 cmpl $64,%ecx 102 jb 3f 103 movl %eax,(%edx) 104 movl %eax,4(%edx) 105 movl %eax,8(%edx) 106 movl %eax,12(%edx) 107 movl %eax,16(%edx) 108 movl %eax,20(%edx) 109 movl %eax,24(%edx) 110 movl %eax,28(%edx) 111 movl %eax,32(%edx) 112 movl %eax,36(%edx) 113 movl %eax,40(%edx) 114 movl %eax,44(%edx) 115 movl %eax,48(%edx) 116 movl %eax,52(%edx) 117 movl %eax,56(%edx) 118 movl %eax,60(%edx) 119 addl $64,%edx 120 subl $64,%ecx 121 jnz 2b 122 ret 123 124/ 125/ do 16 byte chunks 126/ 127 SUPERALIGN_TEXT 1283: 129 cmpl $16,%ecx 130 jb 4f 131 movl %eax,(%edx) 132 movl %eax,4(%edx) 133 movl %eax,8(%edx) 134 movl %eax,12(%edx) 135 addl $16,%edx 136 subl $16,%ecx 137 jnz 3b 138 ret 139 140/ 141/ do 4 byte chunks 142/ 143 SUPERALIGN_TEXT 1444: 145 cmpl $4,%ecx 146 jb 5f 147 movl %eax,(%edx) 148 addl $4,%edx 149 subl $4,%ecx 150 jnz 4b 151 ret 152 153/ 154/ do 1 byte chunks 155/ a jump table seems to be faster than a loop or more range reductions 156/ 157/ XXX need a const section for non-text 158/ 159 SUPERALIGN_TEXT 160jtab: 161 .long do0 162 .long do1 163 .long do2 164 .long do3 165 166 SUPERALIGN_TEXT 1675: 168 jmp jtab(,%ecx,4) 169 170 SUPERALIGN_TEXT 171do3: 172 movw %ax,(%edx) 173 movb %al,2(%edx) 174 ret 175 176 SUPERALIGN_TEXT 177do2: 178 movw %ax,(%edx) 179 ret 180 181 SUPERALIGN_TEXT 182do1: 183 movb %al,(%edx) 184 185 SUPERALIGN_TEXT 186do0: 187 ret 188#endif /* I486_CPU */ 189 190/* fillw(pat, base, cnt) */ 191ENTRY(fillw) 192 pushl %edi 193 movl 8(%esp),%eax 194 movl 12(%esp),%edi 195 movl 16(%esp),%ecx 196 cld 197 rep 198 stosw 199 popl %edi 200 ret 201 202ENTRY(bcopyb) 203bcopyb: 204 pushl %esi 205 pushl %edi 206 movl 12(%esp),%esi 207 movl 16(%esp),%edi 208 movl 20(%esp),%ecx 209 cmpl %esi,%edi /* potentially overlapping? */ 210 jnb 1f 211 cld /* nope, copy forwards */ 212 rep 213 movsb 214 popl %edi 215 popl %esi 216 ret 217 218 ALIGN_TEXT 2191: 220 addl %ecx,%edi /* copy backwards. */ 221 addl %ecx,%esi 222 std 223 decl %edi 224 decl %esi 225 rep 226 movsb 227 popl %edi 228 popl %esi 229 cld 230 ret 231 232/* 233 * (ov)bcopy(src, dst, cnt) 234 * ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800 235 */ 236ALTENTRY(ovbcopy) 237ENTRY(bcopy) 238bcopy: 239 pushl %esi 240 pushl %edi 241 movl 12(%esp),%esi 242 movl 16(%esp),%edi 243 movl 20(%esp),%ecx 244 cmpl %esi,%edi /* potentially overlapping? */ 245 jnb 1f 246 shrl $2,%ecx /* copy by 32-bit words */ 247 cld /* nope, copy forwards */ 248 rep 249 movsl 250 movl 20(%esp),%ecx 251 andl $3,%ecx /* any bytes left? */ 252 rep 253 movsb 254 popl %edi 255 popl %esi 256 ret 257 258 ALIGN_TEXT 2591: 260 addl %ecx,%edi /* copy backwards */ 261 addl %ecx,%esi 262 andl $3,%ecx /* any fractional bytes? */ 263 decl %edi 264 decl %esi 265 std 266 rep 267 movsb 268 movl 20(%esp),%ecx /* copy remainder by 32-bit words */ 269 shrl $2,%ecx 270 subl $3,%esi 271 subl $3,%edi 272 rep 273 movsl 274 popl %edi 275 popl %esi 276 cld 277 ret 278 279 280/* 281 * Note: memcpy does not support overlapping copies 282 */ 283ENTRY(memcpy) 284 pushl %edi 285 pushl %esi 286 movl 12(%esp),%edi 287 movl 16(%esp),%esi 288 movl 20(%esp),%ecx 289 movl %edi,%eax 290 shrl $2,%ecx /* copy by 32-bit words */ 291 cld /* nope, copy forwards */ 292 rep 293 movsl 294 movl 20(%esp),%ecx 295 andl $3,%ecx /* any bytes left? */ 296 rep 297 movsb 298 popl %esi 299 popl %edi 300 ret 301 302 303/*****************************************************************************/ 304/* copyout and fubyte family */ 305/*****************************************************************************/ 306/* 307 * Access user memory from inside the kernel. These routines and possibly 308 * the math- and DOS emulators should be the only places that do this. 309 * 310 * We have to access the memory with user's permissions, so use a segment 311 * selector with RPL 3. For writes to user space we have to additionally 312 * check the PTE for write permission, because the 386 does not check 313 * write permissions when we are executing with EPL 0. The 486 does check 314 * this if the WP bit is set in CR0, so we can use a simpler version here. 315 * 316 * These routines set curpcb->onfault for the time they execute. When a 317 * protection violation occurs inside the functions, the trap handler 318 * returns to *curpcb->onfault instead of the function. 319 */ 320 321 322ENTRY(copyout) /* copyout(from_kernel, to_user, len) */ 323 movl _curpcb,%eax 324 movl $copyout_fault,PCB_ONFAULT(%eax) 325 pushl %esi 326 pushl %edi 327 pushl %ebx 328 movl 16(%esp),%esi 329 movl 20(%esp),%edi 330 movl 24(%esp),%ebx 331 testl %ebx,%ebx /* anything to do? */ 332 jz done_copyout 333 334 /* 335 * Check explicitly for non-user addresses. If 486 write protection 336 * is being used, this check is essential because we are in kernel 337 * mode so the h/w does not provide any protection against writing 338 * kernel addresses. 339 */ 340 341 /* 342 * First, prevent address wrapping. 343 */ 344 movl %edi,%eax 345 addl %ebx,%eax 346 jc copyout_fault 347/* 348 * XXX STOP USING VM_MAXUSER_ADDRESS. 349 * It is an end address, not a max, so every time it is used correctly it 350 * looks like there is an off by one error, and of course it caused an off 351 * by one error in several places. 352 */ 353 cmpl $VM_MAXUSER_ADDRESS,%eax 354 ja copyout_fault 355 356#if defined(I386_CPU) 357 358#if defined(I486_CPU) || defined(I586_CPU) 359 cmpl $CPUCLASS_386,_cpu_class 360 jne 3f 361#endif 362/* 363 * We have to check each PTE for user write permission. 364 * The checking may cause a page fault, so it is important to set 365 * up everything for return via copyout_fault before here. 366 */ 367 /* compute number of pages */ 368 movl %edi,%ecx 369 andl $NBPG-1,%ecx 370 addl %ebx,%ecx 371 decl %ecx 372 shrl $IDXSHIFT+2,%ecx 373 incl %ecx 374 375 /* compute PTE offset for start address */ 376 movl %edi,%edx 377 shrl $IDXSHIFT,%edx 378 andb $0xfc,%dl 379 3801: /* check PTE for each page */ 381 movb _PTmap(%edx),%al 382 andb $0x07,%al /* Pages must be VALID + USERACC + WRITABLE */ 383 cmpb $0x07,%al 384 je 2f 385 386 /* simulate a trap */ 387 pushl %edx 388 pushl %ecx 389 shll $IDXSHIFT,%edx 390 pushl %edx 391 call _trapwrite /* trapwrite(addr) */ 392 popl %edx 393 popl %ecx 394 popl %edx 395 396 testl %eax,%eax /* if not ok, return EFAULT */ 397 jnz copyout_fault 398 3992: 400 addl $4,%edx 401 decl %ecx 402 jnz 1b /* check next page */ 403#endif /* I386_CPU */ 404 405 /* bcopy(%esi, %edi, %ebx) */ 4063: 407 movl %ebx,%ecx 408 shrl $2,%ecx 409 cld 410 rep 411 movsl 412 movb %bl,%cl 413 andb $3,%cl 414 rep 415 movsb 416 417done_copyout: 418 popl %ebx 419 popl %edi 420 popl %esi 421 xorl %eax,%eax 422 movl _curpcb,%edx 423 movl %eax,PCB_ONFAULT(%edx) 424 ret 425 426 ALIGN_TEXT 427copyout_fault: 428 popl %ebx 429 popl %edi 430 popl %esi 431 movl _curpcb,%edx 432 movl $0,PCB_ONFAULT(%edx) 433 movl $EFAULT,%eax 434 ret 435 436/* copyin(from_user, to_kernel, len) */ 437ENTRY(copyin) 438 movl _curpcb,%eax 439 movl $copyin_fault,PCB_ONFAULT(%eax) 440 pushl %esi 441 pushl %edi 442 movl 12(%esp),%esi /* caddr_t from */ 443 movl 16(%esp),%edi /* caddr_t to */ 444 movl 20(%esp),%ecx /* size_t len */ 445 446 /* 447 * make sure address is valid 448 */ 449 movl %esi,%edx 450 addl %ecx,%edx 451 jc copyin_fault 452 cmpl $VM_MAXUSER_ADDRESS,%edx 453 ja copyin_fault 454 455 movb %cl,%al 456 shrl $2,%ecx /* copy longword-wise */ 457 cld 458 rep 459 movsl 460 movb %al,%cl 461 andb $3,%cl /* copy remaining bytes */ 462 rep 463 movsb 464 465 popl %edi 466 popl %esi 467 xorl %eax,%eax 468 movl _curpcb,%edx 469 movl %eax,PCB_ONFAULT(%edx) 470 ret 471 472 ALIGN_TEXT 473copyin_fault: 474 popl %edi 475 popl %esi 476 movl _curpcb,%edx 477 movl $0,PCB_ONFAULT(%edx) 478 movl $EFAULT,%eax 479 ret 480 481/* 482 * fu{byte,sword,word} : fetch a byte (sword, word) from user memory 483 */ 484ENTRY(fuword) 485 movl _curpcb,%ecx 486 movl $fusufault,PCB_ONFAULT(%ecx) 487 movl 4(%esp),%edx /* from */ 488 489 cmpl $VM_MAXUSER_ADDRESS-4,%edx /* verify address is valid */ 490 ja fusufault 491 492 movl (%edx),%eax 493 movl $0,PCB_ONFAULT(%ecx) 494 ret 495 496/* 497 * These two routines are called from the profiling code, potentially 498 * at interrupt time. If they fail, that's okay, good things will 499 * happen later. Fail all the time for now - until the trap code is 500 * able to deal with this. 501 */ 502ALTENTRY(suswintr) 503ENTRY(fuswintr) 504 movl $-1,%eax 505 ret 506 507ENTRY(fubyte) 508 movl _curpcb,%ecx 509 movl $fusufault,PCB_ONFAULT(%ecx) 510 movl 4(%esp),%edx 511 512 cmpl $VM_MAXUSER_ADDRESS-1,%edx 513 ja fusufault 514 515 movzbl (%edx),%eax 516 movl $0,PCB_ONFAULT(%ecx) 517 ret 518 519 ALIGN_TEXT 520fusufault: 521 movl _curpcb,%ecx 522 xorl %eax,%eax 523 movl %eax,PCB_ONFAULT(%ecx) 524 decl %eax 525 ret 526 527/* 528 * su{byte,sword,word}: write a byte (word, longword) to user memory 529 */ 530ENTRY(suword) 531 movl _curpcb,%ecx 532 movl $fusufault,PCB_ONFAULT(%ecx) 533 movl 4(%esp),%edx 534 535#if defined(I386_CPU) 536 537#if defined(I486_CPU) || defined(I586_CPU) 538 cmpl $CPUCLASS_386,_cpu_class 539 jne 2f /* we only have to set the right segment selector */ 540#endif /* I486_CPU || I586_CPU */ 541 542 /* XXX - page boundary crossing is still not handled */ 543 movl %edx,%eax 544 shrl $IDXSHIFT,%edx 545 andb $0xfc,%dl 546 movb _PTmap(%edx),%dl 547 andb $0x7,%dl /* must be VALID + USERACC + WRITE */ 548 cmpb $0x7,%dl 549 je 1f 550 551 /* simulate a trap */ 552 pushl %eax 553 call _trapwrite 554 popl %edx /* remove junk parameter from stack */ 555 movl _curpcb,%ecx /* restore trashed register */ 556 testl %eax,%eax 557 jnz fusufault 5581: 559 movl 4(%esp),%edx 560#endif 561 5622: 563 cmpl $VM_MAXUSER_ADDRESS-4,%edx /* verify address validity */ 564 ja fusufault 565 566 movl 8(%esp),%eax 567 movl %eax,(%edx) 568 xorl %eax,%eax 569 movl %eax,PCB_ONFAULT(%ecx) 570 ret 571 572ENTRY(susword) 573 movl _curpcb,%ecx 574 movl $fusufault,PCB_ONFAULT(%ecx) 575 movl 4(%esp),%edx 576 577#if defined(I386_CPU) 578 579#if defined(I486_CPU) || defined(I586_CPU) 580 cmpl $CPUCLASS_386,_cpu_class 581 jne 2f 582#endif /* I486_CPU || I586_CPU */ 583 584 /* XXX - page boundary crossing is still not handled */ 585 movl %edx,%eax 586 shrl $IDXSHIFT,%edx 587 andb $0xfc,%dl 588 movb _PTmap(%edx),%dl 589 andb $0x7,%dl /* must be VALID + USERACC + WRITE */ 590 cmpb $0x7,%dl 591 je 1f 592 593 /* simulate a trap */ 594 pushl %eax 595 call _trapwrite 596 popl %edx /* remove junk parameter from stack */ 597 movl _curpcb,%ecx /* restore trashed register */ 598 testl %eax,%eax 599 jnz fusufault 6001: 601 movl 4(%esp),%edx 602#endif 603 6042: 605 cmpl $VM_MAXUSER_ADDRESS-2,%edx /* verify address validity */ 606 ja fusufault 607 608 movw 8(%esp),%ax 609 movw %ax,(%edx) 610 xorl %eax,%eax 611 movl %eax,PCB_ONFAULT(%ecx) 612 ret 613 614ALTENTRY(suibyte) 615ENTRY(subyte) 616 movl _curpcb,%ecx 617 movl $fusufault,PCB_ONFAULT(%ecx) 618 movl 4(%esp),%edx 619 620#if defined(I386_CPU) 621 622#if defined(I486_CPU) || defined(I586_CPU) 623 cmpl $CPUCLASS_386,_cpu_class 624 jne 2f 625#endif /* I486_CPU || I586_CPU */ 626 627 movl %edx,%eax 628 shrl $IDXSHIFT,%edx 629 andb $0xfc,%dl 630 movb _PTmap(%edx),%dl 631 andb $0x7,%dl /* must be VALID + USERACC + WRITE */ 632 cmpb $0x7,%dl 633 je 1f 634 635 /* simulate a trap */ 636 pushl %eax 637 call _trapwrite 638 popl %edx /* remove junk parameter from stack */ 639 movl _curpcb,%ecx /* restore trashed register */ 640 testl %eax,%eax 641 jnz fusufault 6421: 643 movl 4(%esp),%edx 644#endif 645 6462: 647 cmpl $VM_MAXUSER_ADDRESS-1,%edx /* verify address validity */ 648 ja fusufault 649 650 movb 8(%esp),%al 651 movb %al,(%edx) 652 xorl %eax,%eax 653 movl %eax,PCB_ONFAULT(%ecx) 654 ret 655 656/* 657 * copyinstr(from, to, maxlen, int *lencopied) 658 * copy a string from from to to, stop when a 0 character is reached. 659 * return ENAMETOOLONG if string is longer than maxlen, and 660 * EFAULT on protection violations. If lencopied is non-zero, 661 * return the actual length in *lencopied. 662 */ 663ENTRY(copyinstr) 664 pushl %esi 665 pushl %edi 666 movl _curpcb,%ecx 667 movl $cpystrflt,PCB_ONFAULT(%ecx) 668 669 movl 12(%esp),%esi /* %esi = from */ 670 movl 16(%esp),%edi /* %edi = to */ 671 movl 20(%esp),%edx /* %edx = maxlen */ 672 673 movl $VM_MAXUSER_ADDRESS,%eax 674 675 /* make sure 'from' is within bounds */ 676 subl %esi,%eax 677 jbe cpystrflt 678 679 /* restrict maxlen to <= VM_MAXUSER_ADDRESS-from */ 680 cmpl %edx,%eax 681 jae 1f 682 movl %eax,%edx 683 movl %eax,20(%esp) 6841: 685 incl %edx 686 cld 687 6882: 689 decl %edx 690 jz 3f 691 692 lodsb 693 stosb 694 orb %al,%al 695 jnz 2b 696 697 /* Success -- 0 byte reached */ 698 decl %edx 699 xorl %eax,%eax 700 jmp cpystrflt_x 7013: 702 /* edx is zero - return ENAMETOOLONG or EFAULT */ 703 cmpl $VM_MAXUSER_ADDRESS,%esi 704 jae cpystrflt 7054: 706 movl $ENAMETOOLONG,%eax 707 jmp cpystrflt_x 708 709cpystrflt: 710 movl $EFAULT,%eax 711 712cpystrflt_x: 713 /* set *lencopied and return %eax */ 714 movl _curpcb,%ecx 715 movl $0,PCB_ONFAULT(%ecx) 716 movl 20(%esp),%ecx 717 subl %edx,%ecx 718 movl 24(%esp),%edx 719 testl %edx,%edx 720 jz 1f 721 movl %ecx,(%edx) 7221: 723 popl %edi 724 popl %esi 725 ret 726 727 728/* 729 * copystr(from, to, maxlen, int *lencopied) 730 */ 731ENTRY(copystr) 732 pushl %esi 733 pushl %edi 734 735 movl 12(%esp),%esi /* %esi = from */ 736 movl 16(%esp),%edi /* %edi = to */ 737 movl 20(%esp),%edx /* %edx = maxlen */ 738 incl %edx 739 cld 7401: 741 decl %edx 742 jz 4f 743 lodsb 744 stosb 745 orb %al,%al 746 jnz 1b 747 748 /* Success -- 0 byte reached */ 749 decl %edx 750 xorl %eax,%eax 751 jmp 6f 7524: 753 /* edx is zero -- return ENAMETOOLONG */ 754 movl $ENAMETOOLONG,%eax 755 7566: 757 /* set *lencopied and return %eax */ 758 movl 20(%esp),%ecx 759 subl %edx,%ecx 760 movl 24(%esp),%edx 761 testl %edx,%edx 762 jz 7f 763 movl %ecx,(%edx) 7647: 765 popl %edi 766 popl %esi 767 ret 768 769ENTRY(bcmp) 770 pushl %edi 771 pushl %esi 772 movl 12(%esp),%edi 773 movl 16(%esp),%esi 774 movl 20(%esp),%edx 775 xorl %eax,%eax 776 777 movl %edx,%ecx 778 shrl $2,%ecx 779 cld /* compare forwards */ 780 repe 781 cmpsl 782 jne 1f 783 784 movl %edx,%ecx 785 andl $3,%ecx 786 repe 787 cmpsb 788 je 2f 7891: 790 incl %eax 7912: 792 popl %esi 793 popl %edi 794 ret 795 796 797/* 798 * Handling of special 386 registers and descriptor tables etc 799 */ 800/* void lgdt(struct region_descriptor *rdp); */ 801ENTRY(lgdt) 802 /* reload the descriptor table */ 803 movl 4(%esp),%eax 804 lgdt (%eax) 805 806 /* flush the prefetch q */ 807 jmp 1f 808 nop 8091: 810 /* reload "stale" selectors */ 811 movl $KDSEL,%eax 812 movl %ax,%ds 813 movl %ax,%es 814 movl %ax,%ss 815 816 /* reload code selector by turning return into intersegmental return */ 817 movl (%esp),%eax 818 pushl %eax 819# movl $KCSEL,4(%esp) 820 movl $8,4(%esp) 821 lret 822 823/* 824 * void lidt(struct region_descriptor *rdp); 825 */ 826ENTRY(lidt) 827 movl 4(%esp),%eax 828 lidt (%eax) 829 ret 830 831/* 832 * void lldt(u_short sel) 833 */ 834ENTRY(lldt) 835 lldt 4(%esp) 836 ret 837 838/* 839 * void ltr(u_short sel) 840 */ 841ENTRY(ltr) 842 ltr 4(%esp) 843 ret 844 845/* ssdtosd(*ssdp,*sdp) */ 846ENTRY(ssdtosd) 847 pushl %ebx 848 movl 8(%esp),%ecx 849 movl 8(%ecx),%ebx 850 shll $16,%ebx 851 movl (%ecx),%edx 852 roll $16,%edx 853 movb %dh,%bl 854 movb %dl,%bh 855 rorl $8,%ebx 856 movl 4(%ecx),%eax 857 movw %ax,%dx 858 andl $0xf0000,%eax 859 orl %eax,%ebx 860 movl 12(%esp),%ecx 861 movl %edx,(%ecx) 862 movl %ebx,4(%ecx) 863 popl %ebx 864 ret 865 866/* load_cr0(cr0) */ 867ENTRY(load_cr0) 868 movl 4(%esp),%eax 869 movl %eax,%cr0 870 ret 871 872/* rcr0() */ 873ENTRY(rcr0) 874 movl %cr0,%eax 875 ret 876 877/* rcr3() */ 878ENTRY(rcr3) 879 movl %cr3,%eax 880 ret 881 882/* void load_cr3(caddr_t cr3) */ 883ENTRY(load_cr3) 884 movl 4(%esp),%eax 885 movl %eax,%cr3 886 ret 887 888 889/*****************************************************************************/ 890/* setjump, longjump */ 891/*****************************************************************************/ 892 893ENTRY(setjmp) 894 movl 4(%esp),%eax 895 movl %ebx,(%eax) /* save ebx */ 896 movl %esp,4(%eax) /* save esp */ 897 movl %ebp,8(%eax) /* save ebp */ 898 movl %esi,12(%eax) /* save esi */ 899 movl %edi,16(%eax) /* save edi */ 900 movl (%esp),%edx /* get rta */ 901 movl %edx,20(%eax) /* save eip */ 902 xorl %eax,%eax /* return(0); */ 903 ret 904 905ENTRY(longjmp) 906 movl 4(%esp),%eax 907 movl (%eax),%ebx /* restore ebx */ 908 movl 4(%eax),%esp /* restore esp */ 909 movl 8(%eax),%ebp /* restore ebp */ 910 movl 12(%eax),%esi /* restore esi */ 911 movl 16(%eax),%edi /* restore edi */ 912 movl 20(%eax),%edx /* get rta */ 913 movl %edx,(%esp) /* put in return frame */ 914 xorl %eax,%eax /* return(1); */ 915 incl %eax 916 ret 917 918/* 919 * Here for doing BB-profiling (gcc -a). 920 * We rely on the "bbset" instead, but need a dummy function. 921 */ 922 .text 923 .align 2 924.globl ___bb_init_func 925___bb_init_func: 926 movl 4(%esp),%eax 927 movl $1,(%eax) 928 ret 929 930/* 931 * Pull in everything in libkern for LKM's 932 */ 933 934.globl ___umoddi3 935.globl ___moddi3 936.globl ___udivdi3 937.globl ___divdi3 938.globl _inet_ntoa 939.globl _random 940.globl _scanc 941.globl _skpc 942.globl _strcat 943.globl _strncmp 944.globl _strncpy 945.globl _strcmp 946.globl _strcpy 947.globl ___qdivrem 948