]>
git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/X64/GccInline.c
2 GCC inline implementation of BaseLib processor specific functions.
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
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.
17 #include "BaseLibInternals.h"
23 Used to serialize load and store operations.
25 All loads and stores that proceed calls to this function are guaranteed to be
26 globally visible when this function returns.
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");
43 Enables CPU interrupts.
45 Enables CPU interrupts.
54 __asm__
__volatile__ ("sti"::: "memory");
59 Disables CPU interrupts.
61 Disables CPU interrupts.
70 __asm__
__volatile__ ("cli"::: "memory");
77 Requests CPU to pause for a short period of time.
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.
89 __asm__
__volatile__ ("pause");
94 Generates a breakpoint on the CPU.
96 Generates a breakpoint on the CPU. The breakpoint must be implemented such
97 that code can resume normal execution after the breakpoint.
106 __asm__
__volatile__ ("int $3");
112 Returns a 64-bit Machine Specific Register(MSR).
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
120 @param Index The 32-bit MSR index to read.
122 @return The value of the MSR identified by Index.
134 __asm__
__volatile__ (
136 : "=a" (LowData
), // %0
137 "=d" (HighData
) // %1
141 return (((UINT64
)HighData
) << 32) | LowData
;
145 Writes a 64-bit value to a Machine Specific Register(MSR), and returns the
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
155 @param Index The 32-bit MSR index to write.
156 @param Value The 64-bit value to write to the MSR.
171 LowData
= (UINT32
)(Value
);
172 HighData
= (UINT32
)(Value
>> 32);
174 __asm__
__volatile__ (
188 Reads the current value of the EFLAGS register.
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
194 @return EFLAGS on IA-32 or RFLAGS on X64.
205 __asm__
__volatile__ (
208 : "=r" (Eflags
) // %0
217 Reads the current value of the Control Register 0 (CR0).
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
223 @return The value of the Control Register 0 (CR0).
234 __asm__
__volatile__ (
244 Reads the current value of the Control Register 2 (CR2).
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
250 @return The value of the Control Register 2 (CR2).
261 __asm__
__volatile__ (
270 Reads the current value of the Control Register 3 (CR3).
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
276 @return The value of the Control Register 3 (CR3).
287 __asm__
__volatile__ (
297 Reads the current value of the Control Register 4 (CR4).
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
303 @return The value of the Control Register 4 (CR4).
314 __asm__
__volatile__ (
324 Writes a value to Control Register 0 (CR0).
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.
329 @param Cr0 The value to write to CR0.
331 @return The value written to CR0.
340 __asm__
__volatile__ (
350 Writes a value to Control Register 2 (CR2).
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.
355 @param Cr2 The value to write to CR2.
357 @return The value written to CR2.
366 __asm__
__volatile__ (
376 Writes a value to Control Register 3 (CR3).
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.
381 @param Cr3 The value to write to CR3.
383 @return The value written to CR3.
392 __asm__
__volatile__ (
402 Writes a value to Control Register 4 (CR4).
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.
407 @param Cr4 The value to write to CR4.
409 @return The value written to CR4.
418 __asm__
__volatile__ (
428 Reads the current value of Debug Register 0 (DR0).
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
434 @return The value of Debug Register 0 (DR0).
445 __asm__
__volatile__ (
455 Reads the current value of Debug Register 1 (DR1).
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
461 @return The value of Debug Register 1 (DR1).
472 __asm__
__volatile__ (
482 Reads the current value of Debug Register 2 (DR2).
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
488 @return The value of Debug Register 2 (DR2).
499 __asm__
__volatile__ (
509 Reads the current value of Debug Register 3 (DR3).
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
515 @return The value of Debug Register 3 (DR3).
526 __asm__
__volatile__ (
536 Reads the current value of Debug Register 4 (DR4).
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
542 @return The value of Debug Register 4 (DR4).
553 __asm__
__volatile__ (
563 Reads the current value of Debug Register 5 (DR5).
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
569 @return The value of Debug Register 5 (DR5).
580 __asm__
__volatile__ (
590 Reads the current value of Debug Register 6 (DR6).
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
596 @return The value of Debug Register 6 (DR6).
607 __asm__
__volatile__ (
617 Reads the current value of Debug Register 7 (DR7).
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
623 @return The value of Debug Register 7 (DR7).
634 __asm__
__volatile__ (
644 Writes a value to Debug Register 0 (DR0).
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.
649 @param Dr0 The value to write to Dr0.
651 @return The value written to Debug Register 0 (DR0).
660 __asm__
__volatile__ (
670 Writes a value to Debug Register 1 (DR1).
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.
675 @param Dr1 The value to write to Dr1.
677 @return The value written to Debug Register 1 (DR1).
686 __asm__
__volatile__ (
696 Writes a value to Debug Register 2 (DR2).
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.
701 @param Dr2 The value to write to Dr2.
703 @return The value written to Debug Register 2 (DR2).
712 __asm__
__volatile__ (
722 Writes a value to Debug Register 3 (DR3).
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.
727 @param Dr3 The value to write to Dr3.
729 @return The value written to Debug Register 3 (DR3).
738 __asm__
__volatile__ (
748 Writes a value to Debug Register 4 (DR4).
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.
753 @param Dr4 The value to write to Dr4.
755 @return The value written to Debug Register 4 (DR4).
764 __asm__
__volatile__ (
774 Writes a value to Debug Register 5 (DR5).
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.
779 @param Dr5 The value to write to Dr5.
781 @return The value written to Debug Register 5 (DR5).
790 __asm__
__volatile__ (
800 Writes a value to Debug Register 6 (DR6).
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.
805 @param Dr6 The value to write to Dr6.
807 @return The value written to Debug Register 6 (DR6).
816 __asm__
__volatile__ (
826 Writes a value to Debug Register 7 (DR7).
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.
831 @param Dr7 The value to write to Dr7.
833 @return The value written to Debug Register 7 (DR7).
842 __asm__
__volatile__ (
852 Reads the current value of Code Segment Register (CS).
854 Reads and returns the current value of CS. This function is only available on
857 @return The current value of CS.
868 __asm__
__volatile__ (
878 Reads the current value of Data Segment Register (DS).
880 Reads and returns the current value of DS. This function is only available on
883 @return The current value of DS.
894 __asm__
__volatile__ (
904 Reads the current value of Extra Segment Register (ES).
906 Reads and returns the current value of ES. This function is only available on
909 @return The current value of ES.
920 __asm__
__volatile__ (
930 Reads the current value of FS Data Segment Register (FS).
932 Reads and returns the current value of FS. This function is only available on
935 @return The current value of FS.
946 __asm__
__volatile__ (
956 Reads the current value of GS Data Segment Register (GS).
958 Reads and returns the current value of GS. This function is only available on
961 @return The current value of GS.
972 __asm__
__volatile__ (
982 Reads the current value of Stack Segment Register (SS).
984 Reads and returns the current value of SS. This function is only available on
987 @return The current value of SS.
998 __asm__
__volatile__ (
1008 Reads the current value of Task Register (TR).
1010 Reads and returns the current value of TR. This function is only available on
1013 @return The current value of TR.
1024 __asm__
__volatile__ (
1034 Reads the current Global Descriptor Table Register(GDTR) descriptor.
1036 Reads and returns the current GDTR descriptor and returns it in Gdtr. This
1037 function is only available on IA-32 and X64.
1039 @param Gdtr Pointer to a GDTR descriptor.
1044 InternalX86ReadGdtr (
1045 OUT IA32_DESCRIPTOR
*Gdtr
1048 __asm__
__volatile__ (
1056 Writes the current Global Descriptor Table Register (GDTR) descriptor.
1058 Writes and the current GDTR descriptor specified by Gdtr. This function is
1059 only available on IA-32 and X64.
1061 @param Gdtr Pointer to a GDTR descriptor.
1066 InternalX86WriteGdtr (
1067 IN CONST IA32_DESCRIPTOR
*Gdtr
1070 __asm__
__volatile__ (
1080 Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.
1082 Reads and returns the current IDTR descriptor and returns it in Idtr. This
1083 function is only available on IA-32 and X64.
1085 @param Idtr Pointer to a IDTR descriptor.
1090 InternalX86ReadIdtr (
1091 OUT IA32_DESCRIPTOR
*Idtr
1094 __asm__
__volatile__ (
1102 Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.
1104 Writes the current IDTR descriptor and returns it in Idtr. This function is
1105 only available on IA-32 and X64.
1107 @param Idtr Pointer to a IDTR descriptor.
1112 InternalX86WriteIdtr (
1113 IN CONST IA32_DESCRIPTOR
*Idtr
1116 __asm__
__volatile__ (
1125 Reads the current Local Descriptor Table Register(LDTR) selector.
1127 Reads and returns the current 16-bit LDTR descriptor value. This function is
1128 only available on IA-32 and X64.
1130 @return The current selector of LDT.
1141 __asm__
__volatile__ (
1151 Writes the current Local Descriptor Table Register (GDTR) selector.
1153 Writes and the current LDTR descriptor specified by Ldtr. This function is
1154 only available on IA-32 and X64.
1156 @param Ldtr 16-bit LDTR selector value.
1165 __asm__
__volatile__ (
1174 Save the current floating point/SSE/SSE2 context to a buffer.
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.
1180 @param Buffer Pointer to a buffer to save the floating point/SSE/SSE2 context.
1186 OUT IA32_FX_BUFFER
*Buffer
1189 __asm__
__volatile__ (
1192 : "m" (*Buffer
) // %0
1198 Restores the current floating point/SSE/SSE2 context from a buffer.
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.
1204 @param Buffer Pointer to a buffer to save the floating point/SSE/SSE2 context.
1209 InternalX86FxRestore (
1210 IN CONST IA32_FX_BUFFER
*Buffer
1213 __asm__
__volatile__ (
1216 : "m" (*Buffer
) // %0
1222 Reads the current value of 64-bit MMX Register #0 (MM0).
1224 Reads and returns the current value of MM0. This function is only available
1227 @return The current value of MM0.
1238 __asm__
__volatile__ (
1239 "movd %%mm0, %0 \n\t"
1248 Reads the current value of 64-bit MMX Register #1 (MM1).
1250 Reads and returns the current value of MM1. This function is only available
1253 @return The current value of MM1.
1264 __asm__
__volatile__ (
1265 "movd %%mm1, %0 \n\t"
1274 Reads the current value of 64-bit MMX Register #2 (MM2).
1276 Reads and returns the current value of MM2. This function is only available
1279 @return The current value of MM2.
1290 __asm__
__volatile__ (
1291 "movd %%mm2, %0 \n\t"
1300 Reads the current value of 64-bit MMX Register #3 (MM3).
1302 Reads and returns the current value of MM3. This function is only available
1305 @return The current value of MM3.
1316 __asm__
__volatile__ (
1317 "movd %%mm3, %0 \n\t"
1326 Reads the current value of 64-bit MMX Register #4 (MM4).
1328 Reads and returns the current value of MM4. This function is only available
1331 @return The current value of MM4.
1342 __asm__
__volatile__ (
1343 "movd %%mm4, %0 \n\t"
1352 Reads the current value of 64-bit MMX Register #5 (MM5).
1354 Reads and returns the current value of MM5. This function is only available
1357 @return The current value of MM5.
1368 __asm__
__volatile__ (
1369 "movd %%mm5, %0 \n\t"
1378 Reads the current value of 64-bit MMX Register #6 (MM6).
1380 Reads and returns the current value of MM6. This function is only available
1383 @return The current value of MM6.
1394 __asm__
__volatile__ (
1395 "movd %%mm6, %0 \n\t"
1404 Reads the current value of 64-bit MMX Register #7 (MM7).
1406 Reads and returns the current value of MM7. This function is only available
1409 @return The current value of MM7.
1420 __asm__
__volatile__ (
1421 "movd %%mm7, %0 \n\t"
1430 Writes the current value of 64-bit MMX Register #0 (MM0).
1432 Writes the current value of MM0. This function is only available on IA32 and
1435 @param Value The 64-bit value to write to MM0.
1444 __asm__
__volatile__ (
1445 "movd %0, %%mm0" // %0
1453 Writes the current value of 64-bit MMX Register #1 (MM1).
1455 Writes the current value of MM1. This function is only available on IA32 and
1458 @param Value The 64-bit value to write to MM1.
1467 __asm__
__volatile__ (
1468 "movd %0, %%mm1" // %0
1476 Writes the current value of 64-bit MMX Register #2 (MM2).
1478 Writes the current value of MM2. This function is only available on IA32 and
1481 @param Value The 64-bit value to write to MM2.
1490 __asm__
__volatile__ (
1491 "movd %0, %%mm2" // %0
1499 Writes the current value of 64-bit MMX Register #3 (MM3).
1501 Writes the current value of MM3. This function is only available on IA32 and
1504 @param Value The 64-bit value to write to MM3.
1513 __asm__
__volatile__ (
1514 "movd %0, %%mm3" // %0
1522 Writes the current value of 64-bit MMX Register #4 (MM4).
1524 Writes the current value of MM4. This function is only available on IA32 and
1527 @param Value The 64-bit value to write to MM4.
1536 __asm__
__volatile__ (
1537 "movd %0, %%mm4" // %0
1545 Writes the current value of 64-bit MMX Register #5 (MM5).
1547 Writes the current value of MM5. This function is only available on IA32 and
1550 @param Value The 64-bit value to write to MM5.
1559 __asm__
__volatile__ (
1560 "movd %0, %%mm5" // %0
1568 Writes the current value of 64-bit MMX Register #6 (MM6).
1570 Writes the current value of MM6. This function is only available on IA32 and
1573 @param Value The 64-bit value to write to MM6.
1582 __asm__
__volatile__ (
1583 "movd %0, %%mm6" // %0
1591 Writes the current value of 64-bit MMX Register #7 (MM7).
1593 Writes the current value of MM7. This function is only available on IA32 and
1596 @param Value The 64-bit value to write to MM7.
1605 __asm__
__volatile__ (
1606 "movd %0, %%mm7" // %0
1614 Reads the current value of Time Stamp Counter (TSC).
1616 Reads and returns the current value of TSC. This function is only available
1619 @return The current value of TSC
1631 __asm__
__volatile__ (
1637 return (((UINT64
)HiData
) << 32) | LowData
;
1642 Reads the current value of a Performance Counter (PMC).
1644 Reads and returns the current value of performance counter specified by
1645 Index. This function is only available on IA-32 and X64.
1647 @param Index The 32-bit Performance Counter index to read.
1649 @return The value of the PMC specified by Index.
1661 __asm__
__volatile__ (
1668 return (((UINT64
)HiData
) << 32) | LowData
;
1673 Sets up a monitor buffer that is used by AsmMwait().
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.
1678 @param Eax The value to load into EAX or RAX before executing the MONITOR
1680 @param Ecx The value to load into ECX or RCX before executing the MONITOR
1682 @param Edx The value to load into EDX or RDX before executing the MONITOR
1696 __asm__
__volatile__ (
1709 Executes an MWAIT instruction.
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.
1714 @param Eax The value to load into EAX or RAX before executing the MONITOR
1716 @param Ecx The value to load into ECX or RCX before executing the MONITOR
1729 __asm__
__volatile__ (
1741 Executes a WBINVD instruction.
1743 Executes a WBINVD instruction. This function is only available on IA-32 and
1753 __asm__
__volatile__ ("wbinvd":::"memory");
1758 Executes a INVD instruction.
1760 Executes a INVD instruction. This function is only available on IA-32 and
1770 __asm__
__volatile__ ("invd":::"memory");
1776 Flushes a cache line from all the instruction and data caches within the
1777 coherency domain of the CPU.
1779 Flushed the cache line specified by LinearAddress, and returns LinearAddress.
1780 This function is only available on IA-32 and X64.
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
1788 @return LinearAddress
1793 IN VOID
*LinearAddress
1796 __asm__
__volatile__ (
1799 : "r" (LinearAddress
)
1803 return LinearAddress
;