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