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