1 /** @file 2 GCC inline implementation of BaseLib processor specific functions that use 3 privlidged instructions. 4 5 Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR> 6 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> 7 SPDX-License-Identifier: BSD-2-Clause-Patent 8 9 **/ 10 11 12 #include "BaseLibInternals.h" 13 14 /** 15 Enables CPU interrupts. 16 17 Enables CPU interrupts. 18 19 **/ 20 VOID 21 EFIAPI 22 EnableInterrupts ( 23 VOID 24 ) 25 { 26 __asm__ __volatile__ ("sti"::: "memory"); 27 } 28 29 30 /** 31 Disables CPU interrupts. 32 33 Disables CPU interrupts. 34 35 **/ 36 VOID 37 EFIAPI 38 DisableInterrupts ( 39 VOID 40 ) 41 { 42 __asm__ __volatile__ ("cli"::: "memory"); 43 } 44 45 /** 46 Returns a 64-bit Machine Specific Register(MSR). 47 48 Reads and returns the 64-bit MSR specified by Index. No parameter checking is 49 performed on Index, and some Index values may cause CPU exceptions. The 50 caller must either guarantee that Index is valid, or the caller must set up 51 exception handlers to catch the exceptions. This function is only available 52 on IA-32 and X64. 53 54 @param Index The 32-bit MSR index to read. 55 56 @return The value of the MSR identified by Index. 57 58 **/ 59 UINT64 60 EFIAPI 61 AsmReadMsr64 ( 62 IN UINT32 Index 63 ) 64 { 65 UINT32 LowData; 66 UINT32 HighData; 67 68 __asm__ __volatile__ ( 69 "rdmsr" 70 : "=a" (LowData), // %0 71 "=d" (HighData) // %1 72 : "c" (Index) // %2 73 ); 74 75 return (((UINT64)HighData) << 32) | LowData; 76 } 77 78 /** 79 Writes a 64-bit value to a Machine Specific Register(MSR), and returns the 80 value. 81 82 Writes the 64-bit value specified by Value to the MSR specified by Index. The 83 64-bit value written to the MSR is returned. No parameter checking is 84 performed on Index or Value, and some of these may cause CPU exceptions. The 85 caller must either guarantee that Index and Value are valid, or the caller 86 must establish proper exception handlers. This function is only available on 87 IA-32 and X64. 88 89 @param Index The 32-bit MSR index to write. 90 @param Value The 64-bit value to write to the MSR. 91 92 @return Value 93 94 **/ 95 UINT64 96 EFIAPI 97 AsmWriteMsr64 ( 98 IN UINT32 Index, 99 IN UINT64 Value 100 ) 101 { 102 UINT32 LowData; 103 UINT32 HighData; 104 105 LowData = (UINT32)(Value); 106 HighData = (UINT32)(Value >> 32); 107 108 __asm__ __volatile__ ( 109 "wrmsr" 110 : 111 : "c" (Index), 112 "a" (LowData), 113 "d" (HighData) 114 ); 115 116 return Value; 117 } 118 119 /** 120 Reads the current value of the Control Register 0 (CR0). 121 122 Reads and returns the current value of CR0. This function is only available 123 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 124 X64. 125 126 @return The value of the Control Register 0 (CR0). 127 128 **/ 129 UINTN 130 EFIAPI 131 AsmReadCr0 ( 132 VOID 133 ) 134 { 135 UINTN Data; 136 137 __asm__ __volatile__ ( 138 "mov %%cr0,%0" 139 : "=r" (Data) // %0 140 ); 141 142 return Data; 143 } 144 145 146 /** 147 Reads the current value of the Control Register 2 (CR2). 148 149 Reads and returns the current value of CR2. This function is only available 150 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 151 X64. 152 153 @return The value of the Control Register 2 (CR2). 154 155 **/ 156 UINTN 157 EFIAPI 158 AsmReadCr2 ( 159 VOID 160 ) 161 { 162 UINTN Data; 163 164 __asm__ __volatile__ ( 165 "mov %%cr2, %0" 166 : "=r" (Data) // %0 167 ); 168 169 return Data; 170 } 171 172 /** 173 Reads the current value of the Control Register 3 (CR3). 174 175 Reads and returns the current value of CR3. This function is only available 176 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 177 X64. 178 179 @return The value of the Control Register 3 (CR3). 180 181 **/ 182 UINTN 183 EFIAPI 184 AsmReadCr3 ( 185 VOID 186 ) 187 { 188 UINTN Data; 189 190 __asm__ __volatile__ ( 191 "mov %%cr3, %0" 192 : "=r" (Data) // %0 193 ); 194 195 return Data; 196 } 197 198 199 /** 200 Reads the current value of the Control Register 4 (CR4). 201 202 Reads and returns the current value of CR4. This function is only available 203 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 204 X64. 205 206 @return The value of the Control Register 4 (CR4). 207 208 **/ 209 UINTN 210 EFIAPI 211 AsmReadCr4 ( 212 VOID 213 ) 214 { 215 UINTN Data; 216 217 __asm__ __volatile__ ( 218 "mov %%cr4, %0" 219 : "=r" (Data) // %0 220 ); 221 222 return Data; 223 } 224 225 226 /** 227 Writes a value to Control Register 0 (CR0). 228 229 Writes and returns a new value to CR0. This function is only available on 230 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 231 232 @param Cr0 The value to write to CR0. 233 234 @return The value written to CR0. 235 236 **/ 237 UINTN 238 EFIAPI 239 AsmWriteCr0 ( 240 UINTN Cr0 241 ) 242 { 243 __asm__ __volatile__ ( 244 "mov %0, %%cr0" 245 : 246 : "r" (Cr0) 247 ); 248 return Cr0; 249 } 250 251 252 /** 253 Writes a value to Control Register 2 (CR2). 254 255 Writes and returns a new value to CR2. This function is only available on 256 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 257 258 @param Cr2 The value to write to CR2. 259 260 @return The value written to CR2. 261 262 **/ 263 UINTN 264 EFIAPI 265 AsmWriteCr2 ( 266 UINTN Cr2 267 ) 268 { 269 __asm__ __volatile__ ( 270 "mov %0, %%cr2" 271 : 272 : "r" (Cr2) 273 ); 274 return Cr2; 275 } 276 277 278 /** 279 Writes a value to Control Register 3 (CR3). 280 281 Writes and returns a new value to CR3. This function is only available on 282 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 283 284 @param Cr3 The value to write to CR3. 285 286 @return The value written to CR3. 287 288 **/ 289 UINTN 290 EFIAPI 291 AsmWriteCr3 ( 292 UINTN Cr3 293 ) 294 { 295 __asm__ __volatile__ ( 296 "mov %0, %%cr3" 297 : 298 : "r" (Cr3) 299 ); 300 return Cr3; 301 } 302 303 304 /** 305 Writes a value to Control Register 4 (CR4). 306 307 Writes and returns a new value to CR4. This function is only available on 308 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 309 310 @param Cr4 The value to write to CR4. 311 312 @return The value written to CR4. 313 314 **/ 315 UINTN 316 EFIAPI 317 AsmWriteCr4 ( 318 UINTN Cr4 319 ) 320 { 321 __asm__ __volatile__ ( 322 "mov %0, %%cr4" 323 : 324 : "r" (Cr4) 325 ); 326 return Cr4; 327 } 328 329 330 /** 331 Reads the current value of Debug Register 0 (DR0). 332 333 Reads and returns the current value of DR0. This function is only available 334 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 335 X64. 336 337 @return The value of Debug Register 0 (DR0). 338 339 **/ 340 UINTN 341 EFIAPI 342 AsmReadDr0 ( 343 VOID 344 ) 345 { 346 UINTN Data; 347 348 __asm__ __volatile__ ( 349 "mov %%dr0, %0" 350 : "=r" (Data) 351 ); 352 353 return Data; 354 } 355 356 357 /** 358 Reads the current value of Debug Register 1 (DR1). 359 360 Reads and returns the current value of DR1. This function is only available 361 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 362 X64. 363 364 @return The value of Debug Register 1 (DR1). 365 366 **/ 367 UINTN 368 EFIAPI 369 AsmReadDr1 ( 370 VOID 371 ) 372 { 373 UINTN Data; 374 375 __asm__ __volatile__ ( 376 "mov %%dr1, %0" 377 : "=r" (Data) 378 ); 379 380 return Data; 381 } 382 383 384 /** 385 Reads the current value of Debug Register 2 (DR2). 386 387 Reads and returns the current value of DR2. This function is only available 388 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 389 X64. 390 391 @return The value of Debug Register 2 (DR2). 392 393 **/ 394 UINTN 395 EFIAPI 396 AsmReadDr2 ( 397 VOID 398 ) 399 { 400 UINTN Data; 401 402 __asm__ __volatile__ ( 403 "mov %%dr2, %0" 404 : "=r" (Data) 405 ); 406 407 return Data; 408 } 409 410 411 /** 412 Reads the current value of Debug Register 3 (DR3). 413 414 Reads and returns the current value of DR3. This function is only available 415 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 416 X64. 417 418 @return The value of Debug Register 3 (DR3). 419 420 **/ 421 UINTN 422 EFIAPI 423 AsmReadDr3 ( 424 VOID 425 ) 426 { 427 UINTN Data; 428 429 __asm__ __volatile__ ( 430 "mov %%dr3, %0" 431 : "=r" (Data) 432 ); 433 434 return Data; 435 } 436 437 438 /** 439 Reads the current value of Debug Register 4 (DR4). 440 441 Reads and returns the current value of DR4. This function is only available 442 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 443 X64. 444 445 @return The value of Debug Register 4 (DR4). 446 447 **/ 448 UINTN 449 EFIAPI 450 AsmReadDr4 ( 451 VOID 452 ) 453 { 454 UINTN Data; 455 456 __asm__ __volatile__ ( 457 "mov %%dr4, %0" 458 : "=r" (Data) 459 ); 460 461 return Data; 462 } 463 464 465 /** 466 Reads the current value of Debug Register 5 (DR5). 467 468 Reads and returns the current value of DR5. This function is only available 469 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 470 X64. 471 472 @return The value of Debug Register 5 (DR5). 473 474 **/ 475 UINTN 476 EFIAPI 477 AsmReadDr5 ( 478 VOID 479 ) 480 { 481 UINTN Data; 482 483 __asm__ __volatile__ ( 484 "mov %%dr5, %0" 485 : "=r" (Data) 486 ); 487 488 return Data; 489 } 490 491 492 /** 493 Reads the current value of Debug Register 6 (DR6). 494 495 Reads and returns the current value of DR6. This function is only available 496 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 497 X64. 498 499 @return The value of Debug Register 6 (DR6). 500 501 **/ 502 UINTN 503 EFIAPI 504 AsmReadDr6 ( 505 VOID 506 ) 507 { 508 UINTN Data; 509 510 __asm__ __volatile__ ( 511 "mov %%dr6, %0" 512 : "=r" (Data) 513 ); 514 515 return Data; 516 } 517 518 519 /** 520 Reads the current value of Debug Register 7 (DR7). 521 522 Reads and returns the current value of DR7. This function is only available 523 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on 524 X64. 525 526 @return The value of Debug Register 7 (DR7). 527 528 **/ 529 UINTN 530 EFIAPI 531 AsmReadDr7 ( 532 VOID 533 ) 534 { 535 UINTN Data; 536 537 __asm__ __volatile__ ( 538 "mov %%dr7, %0" 539 : "=r" (Data) 540 ); 541 542 return Data; 543 } 544 545 546 /** 547 Writes a value to Debug Register 0 (DR0). 548 549 Writes and returns a new value to DR0. This function is only available on 550 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 551 552 @param Dr0 The value to write to Dr0. 553 554 @return The value written to Debug Register 0 (DR0). 555 556 **/ 557 UINTN 558 EFIAPI 559 AsmWriteDr0 ( 560 UINTN Dr0 561 ) 562 { 563 __asm__ __volatile__ ( 564 "mov %0, %%dr0" 565 : 566 : "r" (Dr0) 567 ); 568 return Dr0; 569 } 570 571 572 /** 573 Writes a value to Debug Register 1 (DR1). 574 575 Writes and returns a new value to DR1. This function is only available on 576 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 577 578 @param Dr1 The value to write to Dr1. 579 580 @return The value written to Debug Register 1 (DR1). 581 582 **/ 583 UINTN 584 EFIAPI 585 AsmWriteDr1 ( 586 UINTN Dr1 587 ) 588 { 589 __asm__ __volatile__ ( 590 "mov %0, %%dr1" 591 : 592 : "r" (Dr1) 593 ); 594 return Dr1; 595 } 596 597 598 /** 599 Writes a value to Debug Register 2 (DR2). 600 601 Writes and returns a new value to DR2. This function is only available on 602 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 603 604 @param Dr2 The value to write to Dr2. 605 606 @return The value written to Debug Register 2 (DR2). 607 608 **/ 609 UINTN 610 EFIAPI 611 AsmWriteDr2 ( 612 UINTN Dr2 613 ) 614 { 615 __asm__ __volatile__ ( 616 "mov %0, %%dr2" 617 : 618 : "r" (Dr2) 619 ); 620 return Dr2; 621 } 622 623 624 /** 625 Writes a value to Debug Register 3 (DR3). 626 627 Writes and returns a new value to DR3. This function is only available on 628 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 629 630 @param Dr3 The value to write to Dr3. 631 632 @return The value written to Debug Register 3 (DR3). 633 634 **/ 635 UINTN 636 EFIAPI 637 AsmWriteDr3 ( 638 UINTN Dr3 639 ) 640 { 641 __asm__ __volatile__ ( 642 "mov %0, %%dr3" 643 : 644 : "r" (Dr3) 645 ); 646 return Dr3; 647 } 648 649 650 /** 651 Writes a value to Debug Register 4 (DR4). 652 653 Writes and returns a new value to DR4. This function is only available on 654 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 655 656 @param Dr4 The value to write to Dr4. 657 658 @return The value written to Debug Register 4 (DR4). 659 660 **/ 661 UINTN 662 EFIAPI 663 AsmWriteDr4 ( 664 UINTN Dr4 665 ) 666 { 667 __asm__ __volatile__ ( 668 "mov %0, %%dr4" 669 : 670 : "r" (Dr4) 671 ); 672 return Dr4; 673 } 674 675 676 /** 677 Writes a value to Debug Register 5 (DR5). 678 679 Writes and returns a new value to DR5. This function is only available on 680 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 681 682 @param Dr5 The value to write to Dr5. 683 684 @return The value written to Debug Register 5 (DR5). 685 686 **/ 687 UINTN 688 EFIAPI 689 AsmWriteDr5 ( 690 UINTN Dr5 691 ) 692 { 693 __asm__ __volatile__ ( 694 "mov %0, %%dr5" 695 : 696 : "r" (Dr5) 697 ); 698 return Dr5; 699 } 700 701 702 /** 703 Writes a value to Debug Register 6 (DR6). 704 705 Writes and returns a new value to DR6. This function is only available on 706 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 707 708 @param Dr6 The value to write to Dr6. 709 710 @return The value written to Debug Register 6 (DR6). 711 712 **/ 713 UINTN 714 EFIAPI 715 AsmWriteDr6 ( 716 UINTN Dr6 717 ) 718 { 719 __asm__ __volatile__ ( 720 "mov %0, %%dr6" 721 : 722 : "r" (Dr6) 723 ); 724 return Dr6; 725 } 726 727 728 /** 729 Writes a value to Debug Register 7 (DR7). 730 731 Writes and returns a new value to DR7. This function is only available on 732 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. 733 734 @param Dr7 The value to write to Dr7. 735 736 @return The value written to Debug Register 7 (DR7). 737 738 **/ 739 UINTN 740 EFIAPI 741 AsmWriteDr7 ( 742 UINTN Dr7 743 ) 744 { 745 __asm__ __volatile__ ( 746 "mov %0, %%dr7" 747 : 748 : "r" (Dr7) 749 ); 750 return Dr7; 751 } 752 753 754 /** 755 Reads the current value of Code Segment Register (CS). 756 757 Reads and returns the current value of CS. This function is only available on 758 IA-32 and X64. 759 760 @return The current value of CS. 761 762 **/ 763 UINT16 764 EFIAPI 765 AsmReadCs ( 766 VOID 767 ) 768 { 769 UINT16 Data; 770 771 __asm__ __volatile__ ( 772 "mov %%cs, %0" 773 :"=a" (Data) 774 ); 775 776 return Data; 777 } 778 779 780 /** 781 Reads the current value of Data Segment Register (DS). 782 783 Reads and returns the current value of DS. This function is only available on 784 IA-32 and X64. 785 786 @return The current value of DS. 787 788 **/ 789 UINT16 790 EFIAPI 791 AsmReadDs ( 792 VOID 793 ) 794 { 795 UINT16 Data; 796 797 __asm__ __volatile__ ( 798 "mov %%ds, %0" 799 :"=a" (Data) 800 ); 801 802 return Data; 803 } 804 805 806 /** 807 Reads the current value of Extra Segment Register (ES). 808 809 Reads and returns the current value of ES. This function is only available on 810 IA-32 and X64. 811 812 @return The current value of ES. 813 814 **/ 815 UINT16 816 EFIAPI 817 AsmReadEs ( 818 VOID 819 ) 820 { 821 UINT16 Data; 822 823 __asm__ __volatile__ ( 824 "mov %%es, %0" 825 :"=a" (Data) 826 ); 827 828 return Data; 829 } 830 831 832 /** 833 Reads the current value of FS Data Segment Register (FS). 834 835 Reads and returns the current value of FS. This function is only available on 836 IA-32 and X64. 837 838 @return The current value of FS. 839 840 **/ 841 UINT16 842 EFIAPI 843 AsmReadFs ( 844 VOID 845 ) 846 { 847 UINT16 Data; 848 849 __asm__ __volatile__ ( 850 "mov %%fs, %0" 851 :"=a" (Data) 852 ); 853 854 return Data; 855 } 856 857 858 /** 859 Reads the current value of GS Data Segment Register (GS). 860 861 Reads and returns the current value of GS. This function is only available on 862 IA-32 and X64. 863 864 @return The current value of GS. 865 866 **/ 867 UINT16 868 EFIAPI 869 AsmReadGs ( 870 VOID 871 ) 872 { 873 UINT16 Data; 874 875 __asm__ __volatile__ ( 876 "mov %%gs, %0" 877 :"=a" (Data) 878 ); 879 880 return Data; 881 } 882 883 884 /** 885 Reads the current value of Stack Segment Register (SS). 886 887 Reads and returns the current value of SS. This function is only available on 888 IA-32 and X64. 889 890 @return The current value of SS. 891 892 **/ 893 UINT16 894 EFIAPI 895 AsmReadSs ( 896 VOID 897 ) 898 { 899 UINT16 Data; 900 901 __asm__ __volatile__ ( 902 "mov %%ds, %0" 903 :"=a" (Data) 904 ); 905 906 return Data; 907 } 908 909 910 /** 911 Reads the current value of Task Register (TR). 912 913 Reads and returns the current value of TR. This function is only available on 914 IA-32 and X64. 915 916 @return The current value of TR. 917 918 **/ 919 UINT16 920 EFIAPI 921 AsmReadTr ( 922 VOID 923 ) 924 { 925 UINT16 Data; 926 927 __asm__ __volatile__ ( 928 "str %0" 929 : "=r" (Data) 930 ); 931 932 return Data; 933 } 934 935 936 /** 937 Reads the current Global Descriptor Table Register(GDTR) descriptor. 938 939 Reads and returns the current GDTR descriptor and returns it in Gdtr. This 940 function is only available on IA-32 and X64. 941 942 @param Gdtr The pointer to a GDTR descriptor. 943 944 **/ 945 VOID 946 EFIAPI 947 InternalX86ReadGdtr ( 948 OUT IA32_DESCRIPTOR *Gdtr 949 ) 950 { 951 __asm__ __volatile__ ( 952 "sgdt %0" 953 : "=m" (*Gdtr) 954 ); 955 } 956 957 958 /** 959 Writes the current Global Descriptor Table Register (GDTR) descriptor. 960 961 Writes and the current GDTR descriptor specified by Gdtr. This function is 962 only available on IA-32 and X64. 963 964 @param Gdtr The pointer to a GDTR descriptor. 965 966 **/ 967 VOID 968 EFIAPI 969 InternalX86WriteGdtr ( 970 IN CONST IA32_DESCRIPTOR *Gdtr 971 ) 972 { 973 __asm__ __volatile__ ( 974 "lgdt %0" 975 : 976 : "m" (*Gdtr) 977 ); 978 979 } 980 981 982 /** 983 Reads the current Interrupt Descriptor Table Register(GDTR) descriptor. 984 985 Reads and returns the current IDTR descriptor and returns it in Idtr. This 986 function is only available on IA-32 and X64. 987 988 @param Idtr The pointer to a IDTR descriptor. 989 990 **/ 991 VOID 992 EFIAPI 993 InternalX86ReadIdtr ( 994 OUT IA32_DESCRIPTOR *Idtr 995 ) 996 { 997 __asm__ __volatile__ ( 998 "sidt %0" 999 : "=m" (*Idtr) 1000 ); 1001 } 1002 1003 1004 /** 1005 Writes the current Interrupt Descriptor Table Register(GDTR) descriptor. 1006 1007 Writes the current IDTR descriptor and returns it in Idtr. This function is 1008 only available on IA-32 and X64. 1009 1010 @param Idtr The pointer to a IDTR descriptor. 1011 1012 **/ 1013 VOID 1014 EFIAPI 1015 InternalX86WriteIdtr ( 1016 IN CONST IA32_DESCRIPTOR *Idtr 1017 ) 1018 { 1019 __asm__ __volatile__ ( 1020 "lidt %0" 1021 : 1022 : "m" (*Idtr) 1023 ); 1024 } 1025 1026 1027 /** 1028 Reads the current Local Descriptor Table Register(LDTR) selector. 1029 1030 Reads and returns the current 16-bit LDTR descriptor value. This function is 1031 only available on IA-32 and X64. 1032 1033 @return The current selector of LDT. 1034 1035 **/ 1036 UINT16 1037 EFIAPI 1038 AsmReadLdtr ( 1039 VOID 1040 ) 1041 { 1042 UINT16 Data; 1043 1044 __asm__ __volatile__ ( 1045 "sldt %0" 1046 : "=g" (Data) // %0 1047 ); 1048 1049 return Data; 1050 } 1051 1052 1053 /** 1054 Writes the current Local Descriptor Table Register (GDTR) selector. 1055 1056 Writes and the current LDTR descriptor specified by Ldtr. This function is 1057 only available on IA-32 and X64. 1058 1059 @param Ldtr 16-bit LDTR selector value. 1060 1061 **/ 1062 VOID 1063 EFIAPI 1064 AsmWriteLdtr ( 1065 IN UINT16 Ldtr 1066 ) 1067 { 1068 __asm__ __volatile__ ( 1069 "lldtw %0" 1070 : 1071 : "g" (Ldtr) // %0 1072 ); 1073 } 1074 1075 /** 1076 Reads the current value of a Performance Counter (PMC). 1077 1078 Reads and returns the current value of performance counter specified by 1079 Index. This function is only available on IA-32 and X64. 1080 1081 @param Index The 32-bit Performance Counter index to read. 1082 1083 @return The value of the PMC specified by Index. 1084 1085 **/ 1086 UINT64 1087 EFIAPI 1088 AsmReadPmc ( 1089 IN UINT32 Index 1090 ) 1091 { 1092 UINT32 LowData; 1093 UINT32 HiData; 1094 1095 __asm__ __volatile__ ( 1096 "rdpmc" 1097 : "=a" (LowData), 1098 "=d" (HiData) 1099 : "c" (Index) 1100 ); 1101 1102 return (((UINT64)HiData) << 32) | LowData; 1103 } 1104 1105 /** 1106 Sets up a monitor buffer that is used by AsmMwait(). 1107 1108 Executes a MONITOR instruction with the register state specified by Eax, Ecx 1109 and Edx. Returns Eax. This function is only available on IA-32 and X64. 1110 1111 @param Eax The value to load into EAX or RAX before executing the MONITOR 1112 instruction. 1113 @param Ecx The value to load into ECX or RCX before executing the MONITOR 1114 instruction. 1115 @param Edx The value to load into EDX or RDX before executing the MONITOR 1116 instruction. 1117 1118 @return Eax 1119 1120 **/ 1121 UINTN 1122 EFIAPI 1123 AsmMonitor ( 1124 IN UINTN Eax, 1125 IN UINTN Ecx, 1126 IN UINTN Edx 1127 ) 1128 { 1129 __asm__ __volatile__ ( 1130 "monitor" 1131 : 1132 : "a" (Eax), 1133 "c" (Ecx), 1134 "d" (Edx) 1135 ); 1136 1137 return Eax; 1138 } 1139 1140 /** 1141 Executes an MWAIT instruction. 1142 1143 Executes an MWAIT instruction with the register state specified by Eax and 1144 Ecx. Returns Eax. This function is only available on IA-32 and X64. 1145 1146 @param Eax The value to load into EAX or RAX before executing the MONITOR 1147 instruction. 1148 @param Ecx The value to load into ECX or RCX before executing the MONITOR 1149 instruction. 1150 1151 @return Eax 1152 1153 **/ 1154 UINTN 1155 EFIAPI 1156 AsmMwait ( 1157 IN UINTN Eax, 1158 IN UINTN Ecx 1159 ) 1160 { 1161 __asm__ __volatile__ ( 1162 "mwait" 1163 : 1164 : "a" (Eax), 1165 "c" (Ecx) 1166 ); 1167 1168 return Eax; 1169 } 1170 1171 /** 1172 Executes a WBINVD instruction. 1173 1174 Executes a WBINVD instruction. This function is only available on IA-32 and 1175 X64. 1176 1177 **/ 1178 VOID 1179 EFIAPI 1180 AsmWbinvd ( 1181 VOID 1182 ) 1183 { 1184 __asm__ __volatile__ ("wbinvd":::"memory"); 1185 } 1186 1187 /** 1188 Executes a INVD instruction. 1189 1190 Executes a INVD instruction. This function is only available on IA-32 and 1191 X64. 1192 1193 **/ 1194 VOID 1195 EFIAPI 1196 AsmInvd ( 1197 VOID 1198 ) 1199 { 1200 __asm__ __volatile__ ("invd":::"memory"); 1201 1202 } 1203 1204 1205 /** 1206 Flushes a cache line from all the instruction and data caches within the 1207 coherency domain of the CPU. 1208 1209 Flushed the cache line specified by LinearAddress, and returns LinearAddress. 1210 This function is only available on IA-32 and X64. 1211 1212 @param LinearAddress The address of the cache line to flush. If the CPU is 1213 in a physical addressing mode, then LinearAddress is a 1214 physical address. If the CPU is in a virtual 1215 addressing mode, then LinearAddress is a virtual 1216 address. 1217 1218 @return LinearAddress 1219 **/ 1220 VOID * 1221 EFIAPI 1222 AsmFlushCacheLine ( 1223 IN VOID *LinearAddress 1224 ) 1225 { 1226 __asm__ __volatile__ ( 1227 "clflush (%0)" 1228 : 1229 : "r" (LinearAddress) 1230 : "memory" 1231 ); 1232 1233 return LinearAddress; 1234 } 1235