1 /** @file 2 GCC inline implementation of BaseLib processor specific functions. 3 4 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> 5 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php. 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 17 #include "BaseLibInternals.h" 18 19 20 21 22 /** 23 Used to serialize load and store operations. 24 25 All loads and stores that proceed calls to this function are guaranteed to be 26 globally visible when this function returns. 27 28 **/ 29 VOID 30 EFIAPI 31 MemoryFence ( 32 VOID 33 ) 34 { 35 // This is a little bit of overkill and it is more about the compiler that it is 36 // actually processor synchronization. This is like the _ReadWriteBarrier 37 // Microsoft specific intrinsic 38 __asm__ __volatile__ ("":::"memory"); 39 } 40 41 42 /** 43 Enables CPU interrupts. 44 45 Enables CPU interrupts. 46 47 **/ 48 VOID 49 EFIAPI 50 EnableInterrupts ( 51 VOID 52 ) 53 { 54 __asm__ __volatile__ ("sti"::: "memory"); 55 } 56 57 58 /** 59 Disables CPU interrupts. 60 61 Disables CPU interrupts. 62 63 **/ 64 VOID 65 EFIAPI 66 DisableInterrupts ( 67 VOID 68 ) 69 { 70 __asm__ __volatile__ ("cli"::: "memory"); 71 } 72 73 74 75 76 /** 77 Requests CPU to pause for a short period of time. 78 79 Requests CPU to pause for a short period of time. Typically used in MP 80 systems to prevent memory starvation while waiting for a spin lock. 81 82 **/ 83 VOID 84 EFIAPI 85 CpuPause ( 86 VOID 87 ) 88 { 89 __asm__ __volatile__ ("pause"); 90 } 91 92 93 /** 94 Generates a breakpoint on the CPU. 95 96 Generates a breakpoint on the CPU. The breakpoint must be implemented such 97 that code can resume normal execution after the breakpoint. 98 99 **/ 100 VOID 101 EFIAPI 102 CpuBreakpoint ( 103 VOID 104 ) 105 { 106 __asm__ __volatile__ ("int $3"); 107 } 108 109 110 111 /** 112 Returns a 64-bit Machine Specific Register(MSR). 113 114 Reads and returns the 64-bit MSR specified by Index. No parameter checking is 115 performed on Index, and some Index values may cause CPU exceptions. The 116 caller must either guarantee that Index is valid, or the caller must set up 117 exception handlers to catch the exceptions. This function is only available 118 on IA-32 and X64. 119 120 @param Index The 32-bit MSR index to read. 121 122 @return The value of the MSR identified by Index. 123 124 **/ 125 UINT64 126 EFIAPI 127 AsmReadMsr64 ( 128 IN UINT32 Index 129 ) 130 { 131 UINT32 LowData; 132 UINT32 HighData; 133 134 __asm__ __volatile__ ( 135 "rdmsr" 136 : "=a" (LowData), // %0 137 "=d" (HighData) // %1 138 : "c" (Index) // %2 139 ); 140 141 return (((UINT64)HighData) << 32) | LowData; 142 } 143 144 /** 145 Writes a 64-bit value to a Machine Specific Register(MSR), and returns the 146 value. 147 148 Writes the 64-bit value specified by Value to the MSR specified by Index. The 149 64-bit value written to the MSR is returned. No parameter checking is 150 performed on Index or Value, and some of these may cause CPU exceptions. The 151 caller must either guarantee that Index and Value are valid, or the caller 152 must establish proper exception handlers. This function is only available on 153 IA-32 and X64. 154 155 @param Index The 32-bit MSR index to write. 156 @param Value The 64-bit value to write to the MSR. 157 158 @return Value 159 160 **/ 161 UINT64 162 EFIAPI 163 AsmWriteMsr64 ( 164 IN UINT32 Index, 165 IN UINT64 Value 166 ) 167 { 168 UINT32 LowData; 169 UINT32 HighData; 170 171 LowData = (UINT32)(Value); 172 HighData = (UINT32)(Value >> 32); 173 174 __asm__ __volatile__ ( 175 "wrmsr" 176 : 177 : "c" (Index), 178 "a" (LowData), 179 "d" (HighData) 180 ); 181 182 return Value; 183 } 184 185 186 187 /** 188 Reads the current value of the EFLAGS register. 189 190 Reads and returns the current value of the EFLAGS register. This function is 191 only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a 192 64-bit value on X64. 193 194 @return EFLAGS on IA-32 or RFLAGS on X64. 195 196 **/ 197 UINTN 198 EFIAPI 199 AsmReadEflags ( 200 VOID 201 ) 202 { 203 UINTN Eflags; 204 205 __asm__ __volatile__ ( 206 "pushfq \n\t" 207 "pop %0 " 208 : "=r" (Eflags) // %0 209 ); 210 211 return Eflags; 212 } 213 214 215 216 /** 217 Reads the current value of the Control Register 0 (CR0). 218 219 Reads and returns the current value of CR0. This function is only available 220 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 221 X64. 222 223 @return The value of the Control Register 0 (CR0). 224 225 **/ 226 UINTN 227 EFIAPI 228 AsmReadCr0 ( 229 VOID 230 ) 231 { 232 UINTN Data; 233 234 __asm__ __volatile__ ( 235 "mov %%cr0,%0" 236 : "=r" (Data) // %0 237 ); 238 239 return Data; 240 } 241 242 243 /** 244 Reads the current value of the Control Register 2 (CR2). 245 246 Reads and returns the current value of CR2. This function is only available 247 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 248 X64. 249 250 @return The value of the Control Register 2 (CR2). 251 252 **/ 253 UINTN 254 EFIAPI 255 AsmReadCr2 ( 256 VOID 257 ) 258 { 259 UINTN Data; 260 261 __asm__ __volatile__ ( 262 "mov %%cr2, %0" 263 : "=r" (Data) // %0 264 ); 265 266 return Data; 267 } 268 269 /** 270 Reads the current value of the Control Register 3 (CR3). 271 272 Reads and returns the current value of CR3. This function is only available 273 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 274 X64. 275 276 @return The value of the Control Register 3 (CR3). 277 278 **/ 279 UINTN 280 EFIAPI 281 AsmReadCr3 ( 282 VOID 283 ) 284 { 285 UINTN Data; 286 287 __asm__ __volatile__ ( 288 "mov %%cr3, %0" 289 : "=r" (Data) // %0 290 ); 291 292 return Data; 293 } 294 295 296 /** 297 Reads the current value of the Control Register 4 (CR4). 298 299 Reads and returns the current value of CR4. This function is only available 300 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 301 X64. 302 303 @return The value of the Control Register 4 (CR4). 304 305 **/ 306 UINTN 307 EFIAPI 308 AsmReadCr4 ( 309 VOID 310 ) 311 { 312 UINTN Data; 313 314 __asm__ __volatile__ ( 315 "mov %%cr4, %0" 316 : "=r" (Data) // %0 317 ); 318 319 return Data; 320 } 321 322 323 /** 324 Writes a value to Control Register 0 (CR0). 325 326 Writes and returns a new value to CR0. This function is only available on 327 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 328 329 @param Cr0 The value to write to CR0. 330 331 @return The value written to CR0. 332 333 **/ 334 UINTN 335 EFIAPI 336 AsmWriteCr0 ( 337 UINTN Cr0 338 ) 339 { 340 __asm__ __volatile__ ( 341 "mov %0, %%cr0" 342 : 343 : "r" (Cr0) 344 ); 345 return Cr0; 346 } 347 348 349 /** 350 Writes a value to Control Register 2 (CR2). 351 352 Writes and returns a new value to CR2. This function is only available on 353 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 354 355 @param Cr2 The value to write to CR2. 356 357 @return The value written to CR2. 358 359 **/ 360 UINTN 361 EFIAPI 362 AsmWriteCr2 ( 363 UINTN Cr2 364 ) 365 { 366 __asm__ __volatile__ ( 367 "mov %0, %%cr2" 368 : 369 : "r" (Cr2) 370 ); 371 return Cr2; 372 } 373 374 375 /** 376 Writes a value to Control Register 3 (CR3). 377 378 Writes and returns a new value to CR3. This function is only available on 379 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 380 381 @param Cr3 The value to write to CR3. 382 383 @return The value written to CR3. 384 385 **/ 386 UINTN 387 EFIAPI 388 AsmWriteCr3 ( 389 UINTN Cr3 390 ) 391 { 392 __asm__ __volatile__ ( 393 "mov %0, %%cr3" 394 : 395 : "r" (Cr3) 396 ); 397 return Cr3; 398 } 399 400 401 /** 402 Writes a value to Control Register 4 (CR4). 403 404 Writes and returns a new value to CR4. This function is only available on 405 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 406 407 @param Cr4 The value to write to CR4. 408 409 @return The value written to CR4. 410 411 **/ 412 UINTN 413 EFIAPI 414 AsmWriteCr4 ( 415 UINTN Cr4 416 ) 417 { 418 __asm__ __volatile__ ( 419 "mov %0, %%cr4" 420 : 421 : "r" (Cr4) 422 ); 423 return Cr4; 424 } 425 426 427 /** 428 Reads the current value of Debug Register 0 (DR0). 429 430 Reads and returns the current value of DR0. This function is only available 431 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 432 X64. 433 434 @return The value of Debug Register 0 (DR0). 435 436 **/ 437 UINTN 438 EFIAPI 439 AsmReadDr0 ( 440 VOID 441 ) 442 { 443 UINTN Data; 444 445 __asm__ __volatile__ ( 446 "mov %%dr0, %0" 447 : "=r" (Data) 448 ); 449 450 return Data; 451 } 452 453 454 /** 455 Reads the current value of Debug Register 1 (DR1). 456 457 Reads and returns the current value of DR1. This function is only available 458 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 459 X64. 460 461 @return The value of Debug Register 1 (DR1). 462 463 **/ 464 UINTN 465 EFIAPI 466 AsmReadDr1 ( 467 VOID 468 ) 469 { 470 UINTN Data; 471 472 __asm__ __volatile__ ( 473 "mov %%dr1, %0" 474 : "=r" (Data) 475 ); 476 477 return Data; 478 } 479 480 481 /** 482 Reads the current value of Debug Register 2 (DR2). 483 484 Reads and returns the current value of DR2. This function is only available 485 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 486 X64. 487 488 @return The value of Debug Register 2 (DR2). 489 490 **/ 491 UINTN 492 EFIAPI 493 AsmReadDr2 ( 494 VOID 495 ) 496 { 497 UINTN Data; 498 499 __asm__ __volatile__ ( 500 "mov %%dr2, %0" 501 : "=r" (Data) 502 ); 503 504 return Data; 505 } 506 507 508 /** 509 Reads the current value of Debug Register 3 (DR3). 510 511 Reads and returns the current value of DR3. This function is only available 512 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 513 X64. 514 515 @return The value of Debug Register 3 (DR3). 516 517 **/ 518 UINTN 519 EFIAPI 520 AsmReadDr3 ( 521 VOID 522 ) 523 { 524 UINTN Data; 525 526 __asm__ __volatile__ ( 527 "mov %%dr3, %0" 528 : "=r" (Data) 529 ); 530 531 return Data; 532 } 533 534 535 /** 536 Reads the current value of Debug Register 4 (DR4). 537 538 Reads and returns the current value of DR4. This function is only available 539 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 540 X64. 541 542 @return The value of Debug Register 4 (DR4). 543 544 **/ 545 UINTN 546 EFIAPI 547 AsmReadDr4 ( 548 VOID 549 ) 550 { 551 UINTN Data; 552 553 __asm__ __volatile__ ( 554 "mov %%dr4, %0" 555 : "=r" (Data) 556 ); 557 558 return Data; 559 } 560 561 562 /** 563 Reads the current value of Debug Register 5 (DR5). 564 565 Reads and returns the current value of DR5. This function is only available 566 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 567 X64. 568 569 @return The value of Debug Register 5 (DR5). 570 571 **/ 572 UINTN 573 EFIAPI 574 AsmReadDr5 ( 575 VOID 576 ) 577 { 578 UINTN Data; 579 580 __asm__ __volatile__ ( 581 "mov %%dr5, %0" 582 : "=r" (Data) 583 ); 584 585 return Data; 586 } 587 588 589 /** 590 Reads the current value of Debug Register 6 (DR6). 591 592 Reads and returns the current value of DR6. This function is only available 593 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 594 X64. 595 596 @return The value of Debug Register 6 (DR6). 597 598 **/ 599 UINTN 600 EFIAPI 601 AsmReadDr6 ( 602 VOID 603 ) 604 { 605 UINTN Data; 606 607 __asm__ __volatile__ ( 608 "mov %%dr6, %0" 609 : "=r" (Data) 610 ); 611 612 return Data; 613 } 614 615 616 /** 617 Reads the current value of Debug Register 7 (DR7). 618 619 Reads and returns the current value of DR7. This function is only available 620 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 621 X64. 622 623 @return The value of Debug Register 7 (DR7). 624 625 **/ 626 UINTN 627 EFIAPI 628 AsmReadDr7 ( 629 VOID 630 ) 631 { 632 UINTN Data; 633 634 __asm__ __volatile__ ( 635 "mov %%dr7, %0" 636 : "=r" (Data) 637 ); 638 639 return Data; 640 } 641 642 643 /** 644 Writes a value to Debug Register 0 (DR0). 645 646 Writes and returns a new value to DR0. This function is only available on 647 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 648 649 @param Dr0 The value to write to Dr0. 650 651 @return The value written to Debug Register 0 (DR0). 652 653 **/ 654 UINTN 655 EFIAPI 656 AsmWriteDr0 ( 657 UINTN Dr0 658 ) 659 { 660 __asm__ __volatile__ ( 661 "mov %0, %%dr0" 662 : 663 : "r" (Dr0) 664 ); 665 return Dr0; 666 } 667 668 669 /** 670 Writes a value to Debug Register 1 (DR1). 671 672 Writes and returns a new value to DR1. This function is only available on 673 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 674 675 @param Dr1 The value to write to Dr1. 676 677 @return The value written to Debug Register 1 (DR1). 678 679 **/ 680 UINTN 681 EFIAPI 682 AsmWriteDr1 ( 683 UINTN Dr1 684 ) 685 { 686 __asm__ __volatile__ ( 687 "mov %0, %%dr1" 688 : 689 : "r" (Dr1) 690 ); 691 return Dr1; 692 } 693 694 695 /** 696 Writes a value to Debug Register 2 (DR2). 697 698 Writes and returns a new value to DR2. This function is only available on 699 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 700 701 @param Dr2 The value to write to Dr2. 702 703 @return The value written to Debug Register 2 (DR2). 704 705 **/ 706 UINTN 707 EFIAPI 708 AsmWriteDr2 ( 709 UINTN Dr2 710 ) 711 { 712 __asm__ __volatile__ ( 713 "mov %0, %%dr2" 714 : 715 : "r" (Dr2) 716 ); 717 return Dr2; 718 } 719 720 721 /** 722 Writes a value to Debug Register 3 (DR3). 723 724 Writes and returns a new value to DR3. This function is only available on 725 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 726 727 @param Dr3 The value to write to Dr3. 728 729 @return The value written to Debug Register 3 (DR3). 730 731 **/ 732 UINTN 733 EFIAPI 734 AsmWriteDr3 ( 735 UINTN Dr3 736 ) 737 { 738 __asm__ __volatile__ ( 739 "mov %0, %%dr3" 740 : 741 : "r" (Dr3) 742 ); 743 return Dr3; 744 } 745 746 747 /** 748 Writes a value to Debug Register 4 (DR4). 749 750 Writes and returns a new value to DR4. This function is only available on 751 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 752 753 @param Dr4 The value to write to Dr4. 754 755 @return The value written to Debug Register 4 (DR4). 756 757 **/ 758 UINTN 759 EFIAPI 760 AsmWriteDr4 ( 761 UINTN Dr4 762 ) 763 { 764 __asm__ __volatile__ ( 765 "mov %0, %%dr4" 766 : 767 : "r" (Dr4) 768 ); 769 return Dr4; 770 } 771 772 773 /** 774 Writes a value to Debug Register 5 (DR5). 775 776 Writes and returns a new value to DR5. This function is only available on 777 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 778 779 @param Dr5 The value to write to Dr5. 780 781 @return The value written to Debug Register 5 (DR5). 782 783 **/ 784 UINTN 785 EFIAPI 786 AsmWriteDr5 ( 787 UINTN Dr5 788 ) 789 { 790 __asm__ __volatile__ ( 791 "mov %0, %%dr5" 792 : 793 : "r" (Dr5) 794 ); 795 return Dr5; 796 } 797 798 799 /** 800 Writes a value to Debug Register 6 (DR6). 801 802 Writes and returns a new value to DR6. This function is only available on 803 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 804 805 @param Dr6 The value to write to Dr6. 806 807 @return The value written to Debug Register 6 (DR6). 808 809 **/ 810 UINTN 811 EFIAPI 812 AsmWriteDr6 ( 813 UINTN Dr6 814 ) 815 { 816 __asm__ __volatile__ ( 817 "mov %0, %%dr6" 818 : 819 : "r" (Dr6) 820 ); 821 return Dr6; 822 } 823 824 825 /** 826 Writes a value to Debug Register 7 (DR7). 827 828 Writes and returns a new value to DR7. This function is only available on 829 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 830 831 @param Dr7 The value to write to Dr7. 832 833 @return The value written to Debug Register 7 (DR7). 834 835 **/ 836 UINTN 837 EFIAPI 838 AsmWriteDr7 ( 839 UINTN Dr7 840 ) 841 { 842 __asm__ __volatile__ ( 843 "mov %0, %%dr7" 844 : 845 : "r" (Dr7) 846 ); 847 return Dr7; 848 } 849 850 851 /** 852 Reads the current value of Code Segment Register (CS). 853 854 Reads and returns the current value of CS. This function is only available on 855 IA-32 and X64. 856 857 @return The current value of CS. 858 859 **/ 860 UINT16 861 EFIAPI 862 AsmReadCs ( 863 VOID 864 ) 865 { 866 UINT16 Data; 867 868 __asm__ __volatile__ ( 869 "mov %%cs, %0" 870 :"=a" (Data) 871 ); 872 873 return Data; 874 } 875 876 877 /** 878 Reads the current value of Data Segment Register (DS). 879 880 Reads and returns the current value of DS. This function is only available on 881 IA-32 and X64. 882 883 @return The current value of DS. 884 885 **/ 886 UINT16 887 EFIAPI 888 AsmReadDs ( 889 VOID 890 ) 891 { 892 UINT16 Data; 893 894 __asm__ __volatile__ ( 895 "mov %%ds, %0" 896 :"=a" (Data) 897 ); 898 899 return Data; 900 } 901 902 903 /** 904 Reads the current value of Extra Segment Register (ES). 905 906 Reads and returns the current value of ES. This function is only available on 907 IA-32 and X64. 908 909 @return The current value of ES. 910 911 **/ 912 UINT16 913 EFIAPI 914 AsmReadEs ( 915 VOID 916 ) 917 { 918 UINT16 Data; 919 920 __asm__ __volatile__ ( 921 "mov %%es, %0" 922 :"=a" (Data) 923 ); 924 925 return Data; 926 } 927 928 929 /** 930 Reads the current value of FS Data Segment Register (FS). 931 932 Reads and returns the current value of FS. This function is only available on 933 IA-32 and X64. 934 935 @return The current value of FS. 936 937 **/ 938 UINT16 939 EFIAPI 940 AsmReadFs ( 941 VOID 942 ) 943 { 944 UINT16 Data; 945 946 __asm__ __volatile__ ( 947 "mov %%fs, %0" 948 :"=a" (Data) 949 ); 950 951 return Data; 952 } 953 954 955 /** 956 Reads the current value of GS Data Segment Register (GS). 957 958 Reads and returns the current value of GS. This function is only available on 959 IA-32 and X64. 960 961 @return The current value of GS. 962 963 **/ 964 UINT16 965 EFIAPI 966 AsmReadGs ( 967 VOID 968 ) 969 { 970 UINT16 Data; 971 972 __asm__ __volatile__ ( 973 "mov %%gs, %0" 974 :"=a" (Data) 975 ); 976 977 return Data; 978 } 979 980 981 /** 982 Reads the current value of Stack Segment Register (SS). 983 984 Reads and returns the current value of SS. This function is only available on 985 IA-32 and X64. 986 987 @return The current value of SS. 988 989 **/ 990 UINT16 991 EFIAPI 992 AsmReadSs ( 993 VOID 994 ) 995 { 996 UINT16 Data; 997 998 __asm__ __volatile__ ( 999 "mov %%ds, %0" 1000 :"=a" (Data) 1001 ); 1002 1003 return Data; 1004 } 1005 1006 1007 /** 1008 Reads the current value of Task Register (TR). 1009 1010 Reads and returns the current value of TR. This function is only available on 1011 IA-32 and X64. 1012 1013 @return The current value of TR. 1014 1015 **/ 1016 UINT16 1017 EFIAPI 1018 AsmReadTr ( 1019 VOID 1020 ) 1021 { 1022 UINT16 Data; 1023 1024 __asm__ __volatile__ ( 1025 "str %0" 1026 : "=r" (Data) 1027 ); 1028 1029 return Data; 1030 } 1031 1032 1033 /** 1034 Reads the current Global Descriptor Table Register(GDTR) descriptor. 1035 1036 Reads and returns the current GDTR descriptor and returns it in Gdtr. This 1037 function is only available on IA-32 and X64. 1038 1039 @param Gdtr The pointer to a GDTR descriptor. 1040 1041 **/ 1042 VOID 1043 EFIAPI 1044 InternalX86ReadGdtr ( 1045 OUT IA32_DESCRIPTOR *Gdtr 1046 ) 1047 { 1048 __asm__ __volatile__ ( 1049 "sgdt %0" 1050 : "=m" (*Gdtr) 1051 ); 1052 } 1053 1054 1055 /** 1056 Writes the current Global Descriptor Table Register (GDTR) descriptor. 1057 1058 Writes and the current GDTR descriptor specified by Gdtr. This function is 1059 only available on IA-32 and X64. 1060 1061 @param Gdtr The pointer to a GDTR descriptor. 1062 1063 **/ 1064 VOID 1065 EFIAPI 1066 InternalX86WriteGdtr ( 1067 IN CONST IA32_DESCRIPTOR *Gdtr 1068 ) 1069 { 1070 __asm__ __volatile__ ( 1071 "lgdt %0" 1072 : 1073 : "m" (*Gdtr) 1074 ); 1075 1076 } 1077 1078 1079 /** 1080 Reads the current Interrupt Descriptor Table Register(GDTR) descriptor. 1081 1082 Reads and returns the current IDTR descriptor and returns it in Idtr. This 1083 function is only available on IA-32 and X64. 1084 1085 @param Idtr The pointer to a IDTR descriptor. 1086 1087 **/ 1088 VOID 1089 EFIAPI 1090 InternalX86ReadIdtr ( 1091 OUT IA32_DESCRIPTOR *Idtr 1092 ) 1093 { 1094 __asm__ __volatile__ ( 1095 "sidt %0" 1096 : "=m" (*Idtr) 1097 ); 1098 } 1099 1100 1101 /** 1102 Writes the current Interrupt Descriptor Table Register(GDTR) descriptor. 1103 1104 Writes the current IDTR descriptor and returns it in Idtr. This function is 1105 only available on IA-32 and X64. 1106 1107 @param Idtr The pointer to a IDTR descriptor. 1108 1109 **/ 1110 VOID 1111 EFIAPI 1112 InternalX86WriteIdtr ( 1113 IN CONST IA32_DESCRIPTOR *Idtr 1114 ) 1115 { 1116 __asm__ __volatile__ ( 1117 "lidt %0" 1118 : 1119 : "m" (*Idtr) 1120 ); 1121 } 1122 1123 1124 /** 1125 Reads the current Local Descriptor Table Register(LDTR) selector. 1126 1127 Reads and returns the current 16-bit LDTR descriptor value. This function is 1128 only available on IA-32 and X64. 1129 1130 @return The current selector of LDT. 1131 1132 **/ 1133 UINT16 1134 EFIAPI 1135 AsmReadLdtr ( 1136 VOID 1137 ) 1138 { 1139 UINT16 Data; 1140 1141 __asm__ __volatile__ ( 1142 "sldt %0" 1143 : "=g" (Data) // %0 1144 ); 1145 1146 return Data; 1147 } 1148 1149 1150 /** 1151 Writes the current Local Descriptor Table Register (GDTR) selector. 1152 1153 Writes and the current LDTR descriptor specified by Ldtr. This function is 1154 only available on IA-32 and X64. 1155 1156 @param Ldtr 16-bit LDTR selector value. 1157 1158 **/ 1159 VOID 1160 EFIAPI 1161 AsmWriteLdtr ( 1162 IN UINT16 Ldtr 1163 ) 1164 { 1165 __asm__ __volatile__ ( 1166 "lldtw %0" 1167 : 1168 : "g" (Ldtr) // %0 1169 ); 1170 } 1171 1172 1173 /** 1174 Save the current floating point/SSE/SSE2 context to a buffer. 1175 1176 Saves the current floating point/SSE/SSE2 state to the buffer specified by 1177 Buffer. Buffer must be aligned on a 16-byte boundary. This function is only 1178 available on IA-32 and X64. 1179 1180 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context. 1181 1182 **/ 1183 VOID 1184 EFIAPI 1185 InternalX86FxSave ( 1186 OUT IA32_FX_BUFFER *Buffer 1187 ) 1188 { 1189 __asm__ __volatile__ ( 1190 "fxsave %0" 1191 : 1192 : "m" (*Buffer) // %0 1193 ); 1194 } 1195 1196 1197 /** 1198 Restores the current floating point/SSE/SSE2 context from a buffer. 1199 1200 Restores the current floating point/SSE/SSE2 state from the buffer specified 1201 by Buffer. Buffer must be aligned on a 16-byte boundary. This function is 1202 only available on IA-32 and X64. 1203 1204 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context. 1205 1206 **/ 1207 VOID 1208 EFIAPI 1209 InternalX86FxRestore ( 1210 IN CONST IA32_FX_BUFFER *Buffer 1211 ) 1212 { 1213 __asm__ __volatile__ ( 1214 "fxrstor %0" 1215 : 1216 : "m" (*Buffer) // %0 1217 ); 1218 } 1219 1220 1221 /** 1222 Reads the current value of 64-bit MMX Register #0 (MM0). 1223 1224 Reads and returns the current value of MM0. This function is only available 1225 on IA-32 and X64. 1226 1227 @return The current value of MM0. 1228 1229 **/ 1230 UINT64 1231 EFIAPI 1232 AsmReadMm0 ( 1233 VOID 1234 ) 1235 { 1236 UINT64 Data; 1237 1238 __asm__ __volatile__ ( 1239 "movd %%mm0, %0 \n\t" 1240 : "=r" (Data) // %0 1241 ); 1242 1243 return Data; 1244 } 1245 1246 1247 /** 1248 Reads the current value of 64-bit MMX Register #1 (MM1). 1249 1250 Reads and returns the current value of MM1. This function is only available 1251 on IA-32 and X64. 1252 1253 @return The current value of MM1. 1254 1255 **/ 1256 UINT64 1257 EFIAPI 1258 AsmReadMm1 ( 1259 VOID 1260 ) 1261 { 1262 UINT64 Data; 1263 1264 __asm__ __volatile__ ( 1265 "movd %%mm1, %0 \n\t" 1266 : "=r" (Data) // %0 1267 ); 1268 1269 return Data; 1270 } 1271 1272 1273 /** 1274 Reads the current value of 64-bit MMX Register #2 (MM2). 1275 1276 Reads and returns the current value of MM2. This function is only available 1277 on IA-32 and X64. 1278 1279 @return The current value of MM2. 1280 1281 **/ 1282 UINT64 1283 EFIAPI 1284 AsmReadMm2 ( 1285 VOID 1286 ) 1287 { 1288 UINT64 Data; 1289 1290 __asm__ __volatile__ ( 1291 "movd %%mm2, %0 \n\t" 1292 : "=r" (Data) // %0 1293 ); 1294 1295 return Data; 1296 } 1297 1298 1299 /** 1300 Reads the current value of 64-bit MMX Register #3 (MM3). 1301 1302 Reads and returns the current value of MM3. This function is only available 1303 on IA-32 and X64. 1304 1305 @return The current value of MM3. 1306 1307 **/ 1308 UINT64 1309 EFIAPI 1310 AsmReadMm3 ( 1311 VOID 1312 ) 1313 { 1314 UINT64 Data; 1315 1316 __asm__ __volatile__ ( 1317 "movd %%mm3, %0 \n\t" 1318 : "=r" (Data) // %0 1319 ); 1320 1321 return Data; 1322 } 1323 1324 1325 /** 1326 Reads the current value of 64-bit MMX Register #4 (MM4). 1327 1328 Reads and returns the current value of MM4. This function is only available 1329 on IA-32 and X64. 1330 1331 @return The current value of MM4. 1332 1333 **/ 1334 UINT64 1335 EFIAPI 1336 AsmReadMm4 ( 1337 VOID 1338 ) 1339 { 1340 UINT64 Data; 1341 1342 __asm__ __volatile__ ( 1343 "movd %%mm4, %0 \n\t" 1344 : "=r" (Data) // %0 1345 ); 1346 1347 return Data; 1348 } 1349 1350 1351 /** 1352 Reads the current value of 64-bit MMX Register #5 (MM5). 1353 1354 Reads and returns the current value of MM5. This function is only available 1355 on IA-32 and X64. 1356 1357 @return The current value of MM5. 1358 1359 **/ 1360 UINT64 1361 EFIAPI 1362 AsmReadMm5 ( 1363 VOID 1364 ) 1365 { 1366 UINT64 Data; 1367 1368 __asm__ __volatile__ ( 1369 "movd %%mm5, %0 \n\t" 1370 : "=r" (Data) // %0 1371 ); 1372 1373 return Data; 1374 } 1375 1376 1377 /** 1378 Reads the current value of 64-bit MMX Register #6 (MM6). 1379 1380 Reads and returns the current value of MM6. This function is only available 1381 on IA-32 and X64. 1382 1383 @return The current value of MM6. 1384 1385 **/ 1386 UINT64 1387 EFIAPI 1388 AsmReadMm6 ( 1389 VOID 1390 ) 1391 { 1392 UINT64 Data; 1393 1394 __asm__ __volatile__ ( 1395 "movd %%mm6, %0 \n\t" 1396 : "=r" (Data) // %0 1397 ); 1398 1399 return Data; 1400 } 1401 1402 1403 /** 1404 Reads the current value of 64-bit MMX Register #7 (MM7). 1405 1406 Reads and returns the current value of MM7. This function is only available 1407 on IA-32 and X64. 1408 1409 @return The current value of MM7. 1410 1411 **/ 1412 UINT64 1413 EFIAPI 1414 AsmReadMm7 ( 1415 VOID 1416 ) 1417 { 1418 UINT64 Data; 1419 1420 __asm__ __volatile__ ( 1421 "movd %%mm7, %0 \n\t" 1422 : "=r" (Data) // %0 1423 ); 1424 1425 return Data; 1426 } 1427 1428 1429 /** 1430 Writes the current value of 64-bit MMX Register #0 (MM0). 1431 1432 Writes the current value of MM0. This function is only available on IA32 and 1433 X64. 1434 1435 @param Value The 64-bit value to write to MM0. 1436 1437 **/ 1438 VOID 1439 EFIAPI 1440 AsmWriteMm0 ( 1441 IN UINT64 Value 1442 ) 1443 { 1444 __asm__ __volatile__ ( 1445 "movd %0, %%mm0" // %0 1446 : 1447 : "m" (Value) 1448 ); 1449 } 1450 1451 1452 /** 1453 Writes the current value of 64-bit MMX Register #1 (MM1). 1454 1455 Writes the current value of MM1. This function is only available on IA32 and 1456 X64. 1457 1458 @param Value The 64-bit value to write to MM1. 1459 1460 **/ 1461 VOID 1462 EFIAPI 1463 AsmWriteMm1 ( 1464 IN UINT64 Value 1465 ) 1466 { 1467 __asm__ __volatile__ ( 1468 "movd %0, %%mm1" // %0 1469 : 1470 : "m" (Value) 1471 ); 1472 } 1473 1474 1475 /** 1476 Writes the current value of 64-bit MMX Register #2 (MM2). 1477 1478 Writes the current value of MM2. This function is only available on IA32 and 1479 X64. 1480 1481 @param Value The 64-bit value to write to MM2. 1482 1483 **/ 1484 VOID 1485 EFIAPI 1486 AsmWriteMm2 ( 1487 IN UINT64 Value 1488 ) 1489 { 1490 __asm__ __volatile__ ( 1491 "movd %0, %%mm2" // %0 1492 : 1493 : "m" (Value) 1494 ); 1495 } 1496 1497 1498 /** 1499 Writes the current value of 64-bit MMX Register #3 (MM3). 1500 1501 Writes the current value of MM3. This function is only available on IA32 and 1502 X64. 1503 1504 @param Value The 64-bit value to write to MM3. 1505 1506 **/ 1507 VOID 1508 EFIAPI 1509 AsmWriteMm3 ( 1510 IN UINT64 Value 1511 ) 1512 { 1513 __asm__ __volatile__ ( 1514 "movd %0, %%mm3" // %0 1515 : 1516 : "m" (Value) 1517 ); 1518 } 1519 1520 1521 /** 1522 Writes the current value of 64-bit MMX Register #4 (MM4). 1523 1524 Writes the current value of MM4. This function is only available on IA32 and 1525 X64. 1526 1527 @param Value The 64-bit value to write to MM4. 1528 1529 **/ 1530 VOID 1531 EFIAPI 1532 AsmWriteMm4 ( 1533 IN UINT64 Value 1534 ) 1535 { 1536 __asm__ __volatile__ ( 1537 "movd %0, %%mm4" // %0 1538 : 1539 : "m" (Value) 1540 ); 1541 } 1542 1543 1544 /** 1545 Writes the current value of 64-bit MMX Register #5 (MM5). 1546 1547 Writes the current value of MM5. This function is only available on IA32 and 1548 X64. 1549 1550 @param Value The 64-bit value to write to MM5. 1551 1552 **/ 1553 VOID 1554 EFIAPI 1555 AsmWriteMm5 ( 1556 IN UINT64 Value 1557 ) 1558 { 1559 __asm__ __volatile__ ( 1560 "movd %0, %%mm5" // %0 1561 : 1562 : "m" (Value) 1563 ); 1564 } 1565 1566 1567 /** 1568 Writes the current value of 64-bit MMX Register #6 (MM6). 1569 1570 Writes the current value of MM6. This function is only available on IA32 and 1571 X64. 1572 1573 @param Value The 64-bit value to write to MM6. 1574 1575 **/ 1576 VOID 1577 EFIAPI 1578 AsmWriteMm6 ( 1579 IN UINT64 Value 1580 ) 1581 { 1582 __asm__ __volatile__ ( 1583 "movd %0, %%mm6" // %0 1584 : 1585 : "m" (Value) 1586 ); 1587 } 1588 1589 1590 /** 1591 Writes the current value of 64-bit MMX Register #7 (MM7). 1592 1593 Writes the current value of MM7. This function is only available on IA32 and 1594 X64. 1595 1596 @param Value The 64-bit value to write to MM7. 1597 1598 **/ 1599 VOID 1600 EFIAPI 1601 AsmWriteMm7 ( 1602 IN UINT64 Value 1603 ) 1604 { 1605 __asm__ __volatile__ ( 1606 "movd %0, %%mm7" // %0 1607 : 1608 : "m" (Value) 1609 ); 1610 } 1611 1612 1613 /** 1614 Reads the current value of Time Stamp Counter (TSC). 1615 1616 Reads and returns the current value of TSC. This function is only available 1617 on IA-32 and X64. 1618 1619 @return The current value of TSC 1620 1621 **/ 1622 UINT64 1623 EFIAPI 1624 AsmReadTsc ( 1625 VOID 1626 ) 1627 { 1628 UINT32 LowData; 1629 UINT32 HiData; 1630 1631 __asm__ __volatile__ ( 1632 "rdtsc" 1633 : "=a" (LowData), 1634 "=d" (HiData) 1635 ); 1636 1637 return (((UINT64)HiData) << 32) | LowData; 1638 } 1639 1640 1641 /** 1642 Reads the current value of a Performance Counter (PMC). 1643 1644 Reads and returns the current value of performance counter specified by 1645 Index. This function is only available on IA-32 and X64. 1646 1647 @param Index The 32-bit Performance Counter index to read. 1648 1649 @return The value of the PMC specified by Index. 1650 1651 **/ 1652 UINT64 1653 EFIAPI 1654 AsmReadPmc ( 1655 IN UINT32 Index 1656 ) 1657 { 1658 UINT32 LowData; 1659 UINT32 HiData; 1660 1661 __asm__ __volatile__ ( 1662 "rdpmc" 1663 : "=a" (LowData), 1664 "=d" (HiData) 1665 : "c" (Index) 1666 ); 1667 1668 return (((UINT64)HiData) << 32) | LowData; 1669 } 1670 1671 1672 /** 1673 Sets up a monitor buffer that is used by AsmMwait(). 1674 1675 Executes a MONITOR instruction with the register state specified by Eax, Ecx 1676 and Edx. Returns Eax. This function is only available on IA-32 and X64. 1677 1678 @param Eax The value to load into EAX or RAX before executing the MONITOR 1679 instruction. 1680 @param Ecx The value to load into ECX or RCX before executing the MONITOR 1681 instruction. 1682 @param Edx The value to load into EDX or RDX before executing the MONITOR 1683 instruction. 1684 1685 @return Eax 1686 1687 **/ 1688 UINTN 1689 EFIAPI 1690 AsmMonitor ( 1691 IN UINTN Eax, 1692 IN UINTN Ecx, 1693 IN UINTN Edx 1694 ) 1695 { 1696 __asm__ __volatile__ ( 1697 "monitor" 1698 : 1699 : "a" (Eax), 1700 "c" (Ecx), 1701 "d" (Edx) 1702 ); 1703 1704 return Eax; 1705 } 1706 1707 1708 /** 1709 Executes an MWAIT instruction. 1710 1711 Executes an MWAIT instruction with the register state specified by Eax and 1712 Ecx. Returns Eax. This function is only available on IA-32 and X64. 1713 1714 @param Eax The value to load into EAX or RAX before executing the MONITOR 1715 instruction. 1716 @param Ecx The value to load into ECX or RCX before executing the MONITOR 1717 instruction. 1718 1719 @return Eax 1720 1721 **/ 1722 UINTN 1723 EFIAPI 1724 AsmMwait ( 1725 IN UINTN Eax, 1726 IN UINTN Ecx 1727 ) 1728 { 1729 __asm__ __volatile__ ( 1730 "mwait" 1731 : 1732 : "a" (Eax), 1733 "c" (Ecx) 1734 ); 1735 1736 return Eax; 1737 } 1738 1739 1740 /** 1741 Executes a WBINVD instruction. 1742 1743 Executes a WBINVD instruction. This function is only available on IA-32 and 1744 X64. 1745 1746 **/ 1747 VOID 1748 EFIAPI 1749 AsmWbinvd ( 1750 VOID 1751 ) 1752 { 1753 __asm__ __volatile__ ("wbinvd":::"memory"); 1754 } 1755 1756 1757 /** 1758 Executes a INVD instruction. 1759 1760 Executes a INVD instruction. This function is only available on IA-32 and 1761 X64. 1762 1763 **/ 1764 VOID 1765 EFIAPI 1766 AsmInvd ( 1767 VOID 1768 ) 1769 { 1770 __asm__ __volatile__ ("invd":::"memory"); 1771 1772 } 1773 1774 1775 /** 1776 Flushes a cache line from all the instruction and data caches within the 1777 coherency domain of the CPU. 1778 1779 Flushed the cache line specified by LinearAddress, and returns LinearAddress. 1780 This function is only available on IA-32 and X64. 1781 1782 @param LinearAddress The address of the cache line to flush. If the CPU is 1783 in a physical addressing mode, then LinearAddress is a 1784 physical address. If the CPU is in a virtual 1785 addressing mode, then LinearAddress is a virtual 1786 address. 1787 1788 @return LinearAddress 1789 **/ 1790 VOID * 1791 EFIAPI 1792 AsmFlushCacheLine ( 1793 IN VOID *LinearAddress 1794 ) 1795 { 1796 __asm__ __volatile__ ( 1797 "clflush (%0)" 1798 : 1799 : "r" (LinearAddress) 1800 : "memory" 1801 ); 1802 1803 return LinearAddress; 1804 } 1805 1806 1807