Home | History | Annotate | Download | only in X64
      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