]>
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 - 2018, Intel Corporation. All rights reserved.<BR>
5 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include "BaseLibInternals.h"
17 Used to serialize load and store operations.
19 All loads and stores that proceed calls to this function are guaranteed to be
20 globally visible when this function returns.
29 // This is a little bit of overkill and it is more about the compiler that it is
30 // actually processor synchronization. This is like the _ReadWriteBarrier
31 // Microsoft specific intrinsic
32 __asm__
__volatile__ ("":::"memory");
37 Enables CPU interrupts.
39 Enables CPU interrupts.
48 __asm__
__volatile__ ("sti"::: "memory");
53 Disables CPU interrupts.
55 Disables CPU interrupts.
64 __asm__
__volatile__ ("cli"::: "memory");
71 Requests CPU to pause for a short period of time.
73 Requests CPU to pause for a short period of time. Typically used in MP
74 systems to prevent memory starvation while waiting for a spin lock.
83 __asm__
__volatile__ ("pause");
88 Generates a breakpoint on the CPU.
90 Generates a breakpoint on the CPU. The breakpoint must be implemented such
91 that code can resume normal execution after the breakpoint.
100 __asm__
__volatile__ ("int $3");
106 Returns a 64-bit Machine Specific Register(MSR).
108 Reads and returns the 64-bit MSR specified by Index. No parameter checking is
109 performed on Index, and some Index values may cause CPU exceptions. The
110 caller must either guarantee that Index is valid, or the caller must set up
111 exception handlers to catch the exceptions. This function is only available
114 @param Index The 32-bit MSR index to read.
116 @return The value of the MSR identified by Index.
128 __asm__
__volatile__ (
130 : "=a" (LowData
), // %0
131 "=d" (HighData
) // %1
135 return (((UINT64
)HighData
) << 32) | LowData
;
139 Writes a 64-bit value to a Machine Specific Register(MSR), and returns the
142 Writes the 64-bit value specified by Value to the MSR specified by Index. The
143 64-bit value written to the MSR is returned. No parameter checking is
144 performed on Index or Value, and some of these may cause CPU exceptions. The
145 caller must either guarantee that Index and Value are valid, or the caller
146 must establish proper exception handlers. This function is only available on
149 @param Index The 32-bit MSR index to write.
150 @param Value The 64-bit value to write to the MSR.
165 LowData
= (UINT32
)(Value
);
166 HighData
= (UINT32
)(Value
>> 32);
168 __asm__
__volatile__ (
182 Reads the current value of the EFLAGS register.
184 Reads and returns the current value of the EFLAGS register. This function is
185 only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a
188 @return EFLAGS on IA-32 or RFLAGS on X64.
199 __asm__
__volatile__ (
202 : "=r" (Eflags
) // %0
211 Reads the current value of the Control Register 0 (CR0).
213 Reads and returns the current value of CR0. This function is only available
214 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
217 @return The value of the Control Register 0 (CR0).
228 __asm__
__volatile__ (
238 Reads the current value of the Control Register 2 (CR2).
240 Reads and returns the current value of CR2. This function is only available
241 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
244 @return The value of the Control Register 2 (CR2).
255 __asm__
__volatile__ (
264 Reads the current value of the Control Register 3 (CR3).
266 Reads and returns the current value of CR3. This function is only available
267 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
270 @return The value of the Control Register 3 (CR3).
281 __asm__
__volatile__ (
291 Reads the current value of the Control Register 4 (CR4).
293 Reads and returns the current value of CR4. This function is only available
294 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
297 @return The value of the Control Register 4 (CR4).
308 __asm__
__volatile__ (
318 Writes a value to Control Register 0 (CR0).
320 Writes and returns a new value to CR0. This function is only available on
321 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
323 @param Cr0 The value to write to CR0.
325 @return The value written to CR0.
334 __asm__
__volatile__ (
344 Writes a value to Control Register 2 (CR2).
346 Writes and returns a new value to CR2. This function is only available on
347 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
349 @param Cr2 The value to write to CR2.
351 @return The value written to CR2.
360 __asm__
__volatile__ (
370 Writes a value to Control Register 3 (CR3).
372 Writes and returns a new value to CR3. This function is only available on
373 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
375 @param Cr3 The value to write to CR3.
377 @return The value written to CR3.
386 __asm__
__volatile__ (
396 Writes a value to Control Register 4 (CR4).
398 Writes and returns a new value to CR4. This function is only available on
399 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
401 @param Cr4 The value to write to CR4.
403 @return The value written to CR4.
412 __asm__
__volatile__ (
422 Reads the current value of Debug Register 0 (DR0).
424 Reads and returns the current value of DR0. This function is only available
425 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
428 @return The value of Debug Register 0 (DR0).
439 __asm__
__volatile__ (
449 Reads the current value of Debug Register 1 (DR1).
451 Reads and returns the current value of DR1. This function is only available
452 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
455 @return The value of Debug Register 1 (DR1).
466 __asm__
__volatile__ (
476 Reads the current value of Debug Register 2 (DR2).
478 Reads and returns the current value of DR2. This function is only available
479 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
482 @return The value of Debug Register 2 (DR2).
493 __asm__
__volatile__ (
503 Reads the current value of Debug Register 3 (DR3).
505 Reads and returns the current value of DR3. This function is only available
506 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
509 @return The value of Debug Register 3 (DR3).
520 __asm__
__volatile__ (
530 Reads the current value of Debug Register 4 (DR4).
532 Reads and returns the current value of DR4. This function is only available
533 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
536 @return The value of Debug Register 4 (DR4).
547 __asm__
__volatile__ (
557 Reads the current value of Debug Register 5 (DR5).
559 Reads and returns the current value of DR5. This function is only available
560 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
563 @return The value of Debug Register 5 (DR5).
574 __asm__
__volatile__ (
584 Reads the current value of Debug Register 6 (DR6).
586 Reads and returns the current value of DR6. This function is only available
587 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
590 @return The value of Debug Register 6 (DR6).
601 __asm__
__volatile__ (
611 Reads the current value of Debug Register 7 (DR7).
613 Reads and returns the current value of DR7. This function is only available
614 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
617 @return The value of Debug Register 7 (DR7).
628 __asm__
__volatile__ (
638 Writes a value to Debug Register 0 (DR0).
640 Writes and returns a new value to DR0. This function is only available on
641 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
643 @param Dr0 The value to write to Dr0.
645 @return The value written to Debug Register 0 (DR0).
654 __asm__
__volatile__ (
664 Writes a value to Debug Register 1 (DR1).
666 Writes and returns a new value to DR1. This function is only available on
667 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
669 @param Dr1 The value to write to Dr1.
671 @return The value written to Debug Register 1 (DR1).
680 __asm__
__volatile__ (
690 Writes a value to Debug Register 2 (DR2).
692 Writes and returns a new value to DR2. This function is only available on
693 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
695 @param Dr2 The value to write to Dr2.
697 @return The value written to Debug Register 2 (DR2).
706 __asm__
__volatile__ (
716 Writes a value to Debug Register 3 (DR3).
718 Writes and returns a new value to DR3. This function is only available on
719 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
721 @param Dr3 The value to write to Dr3.
723 @return The value written to Debug Register 3 (DR3).
732 __asm__
__volatile__ (
742 Writes a value to Debug Register 4 (DR4).
744 Writes and returns a new value to DR4. This function is only available on
745 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
747 @param Dr4 The value to write to Dr4.
749 @return The value written to Debug Register 4 (DR4).
758 __asm__
__volatile__ (
768 Writes a value to Debug Register 5 (DR5).
770 Writes and returns a new value to DR5. This function is only available on
771 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
773 @param Dr5 The value to write to Dr5.
775 @return The value written to Debug Register 5 (DR5).
784 __asm__
__volatile__ (
794 Writes a value to Debug Register 6 (DR6).
796 Writes and returns a new value to DR6. This function is only available on
797 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
799 @param Dr6 The value to write to Dr6.
801 @return The value written to Debug Register 6 (DR6).
810 __asm__
__volatile__ (
820 Writes a value to Debug Register 7 (DR7).
822 Writes and returns a new value to DR7. This function is only available on
823 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
825 @param Dr7 The value to write to Dr7.
827 @return The value written to Debug Register 7 (DR7).
836 __asm__
__volatile__ (
846 Reads the current value of Code Segment Register (CS).
848 Reads and returns the current value of CS. This function is only available on
851 @return The current value of CS.
862 __asm__
__volatile__ (
872 Reads the current value of Data Segment Register (DS).
874 Reads and returns the current value of DS. This function is only available on
877 @return The current value of DS.
888 __asm__
__volatile__ (
898 Reads the current value of Extra Segment Register (ES).
900 Reads and returns the current value of ES. This function is only available on
903 @return The current value of ES.
914 __asm__
__volatile__ (
924 Reads the current value of FS Data Segment Register (FS).
926 Reads and returns the current value of FS. This function is only available on
929 @return The current value of FS.
940 __asm__
__volatile__ (
950 Reads the current value of GS Data Segment Register (GS).
952 Reads and returns the current value of GS. This function is only available on
955 @return The current value of GS.
966 __asm__
__volatile__ (
976 Reads the current value of Stack Segment Register (SS).
978 Reads and returns the current value of SS. This function is only available on
981 @return The current value of SS.
992 __asm__
__volatile__ (
1002 Reads the current value of Task Register (TR).
1004 Reads and returns the current value of TR. This function is only available on
1007 @return The current value of TR.
1018 __asm__
__volatile__ (
1028 Reads the current Global Descriptor Table Register(GDTR) descriptor.
1030 Reads and returns the current GDTR descriptor and returns it in Gdtr. This
1031 function is only available on IA-32 and X64.
1033 @param Gdtr The pointer to a GDTR descriptor.
1038 InternalX86ReadGdtr (
1039 OUT IA32_DESCRIPTOR
*Gdtr
1042 __asm__
__volatile__ (
1050 Writes the current Global Descriptor Table Register (GDTR) descriptor.
1052 Writes and the current GDTR descriptor specified by Gdtr. This function is
1053 only available on IA-32 and X64.
1055 @param Gdtr The pointer to a GDTR descriptor.
1060 InternalX86WriteGdtr (
1061 IN CONST IA32_DESCRIPTOR
*Gdtr
1064 __asm__
__volatile__ (
1074 Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.
1076 Reads and returns the current IDTR descriptor and returns it in Idtr. This
1077 function is only available on IA-32 and X64.
1079 @param Idtr The pointer to a IDTR descriptor.
1084 InternalX86ReadIdtr (
1085 OUT IA32_DESCRIPTOR
*Idtr
1088 __asm__
__volatile__ (
1096 Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.
1098 Writes the current IDTR descriptor and returns it in Idtr. This function is
1099 only available on IA-32 and X64.
1101 @param Idtr The pointer to a IDTR descriptor.
1106 InternalX86WriteIdtr (
1107 IN CONST IA32_DESCRIPTOR
*Idtr
1110 __asm__
__volatile__ (
1119 Reads the current Local Descriptor Table Register(LDTR) selector.
1121 Reads and returns the current 16-bit LDTR descriptor value. This function is
1122 only available on IA-32 and X64.
1124 @return The current selector of LDT.
1135 __asm__
__volatile__ (
1145 Writes the current Local Descriptor Table Register (GDTR) selector.
1147 Writes and the current LDTR descriptor specified by Ldtr. This function is
1148 only available on IA-32 and X64.
1150 @param Ldtr 16-bit LDTR selector value.
1159 __asm__
__volatile__ (
1168 Save the current floating point/SSE/SSE2 context to a buffer.
1170 Saves the current floating point/SSE/SSE2 state to the buffer specified by
1171 Buffer. Buffer must be aligned on a 16-byte boundary. This function is only
1172 available on IA-32 and X64.
1174 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
1180 OUT IA32_FX_BUFFER
*Buffer
1183 __asm__
__volatile__ (
1186 : "m" (*Buffer
) // %0
1192 Restores the current floating point/SSE/SSE2 context from a buffer.
1194 Restores the current floating point/SSE/SSE2 state from the buffer specified
1195 by Buffer. Buffer must be aligned on a 16-byte boundary. This function is
1196 only available on IA-32 and X64.
1198 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
1203 InternalX86FxRestore (
1204 IN CONST IA32_FX_BUFFER
*Buffer
1207 __asm__
__volatile__ (
1210 : "m" (*Buffer
) // %0
1216 Reads the current value of 64-bit MMX Register #0 (MM0).
1218 Reads and returns the current value of MM0. This function is only available
1221 @return The current value of MM0.
1232 __asm__
__volatile__ (
1233 "movd %%mm0, %0 \n\t"
1242 Reads the current value of 64-bit MMX Register #1 (MM1).
1244 Reads and returns the current value of MM1. This function is only available
1247 @return The current value of MM1.
1258 __asm__
__volatile__ (
1259 "movd %%mm1, %0 \n\t"
1268 Reads the current value of 64-bit MMX Register #2 (MM2).
1270 Reads and returns the current value of MM2. This function is only available
1273 @return The current value of MM2.
1284 __asm__
__volatile__ (
1285 "movd %%mm2, %0 \n\t"
1294 Reads the current value of 64-bit MMX Register #3 (MM3).
1296 Reads and returns the current value of MM3. This function is only available
1299 @return The current value of MM3.
1310 __asm__
__volatile__ (
1311 "movd %%mm3, %0 \n\t"
1320 Reads the current value of 64-bit MMX Register #4 (MM4).
1322 Reads and returns the current value of MM4. This function is only available
1325 @return The current value of MM4.
1336 __asm__
__volatile__ (
1337 "movd %%mm4, %0 \n\t"
1346 Reads the current value of 64-bit MMX Register #5 (MM5).
1348 Reads and returns the current value of MM5. This function is only available
1351 @return The current value of MM5.
1362 __asm__
__volatile__ (
1363 "movd %%mm5, %0 \n\t"
1372 Reads the current value of 64-bit MMX Register #6 (MM6).
1374 Reads and returns the current value of MM6. This function is only available
1377 @return The current value of MM6.
1388 __asm__
__volatile__ (
1389 "movd %%mm6, %0 \n\t"
1398 Reads the current value of 64-bit MMX Register #7 (MM7).
1400 Reads and returns the current value of MM7. This function is only available
1403 @return The current value of MM7.
1414 __asm__
__volatile__ (
1415 "movd %%mm7, %0 \n\t"
1424 Writes the current value of 64-bit MMX Register #0 (MM0).
1426 Writes the current value of MM0. This function is only available on IA32 and
1429 @param Value The 64-bit value to write to MM0.
1438 __asm__
__volatile__ (
1439 "movd %0, %%mm0" // %0
1447 Writes the current value of 64-bit MMX Register #1 (MM1).
1449 Writes the current value of MM1. This function is only available on IA32 and
1452 @param Value The 64-bit value to write to MM1.
1461 __asm__
__volatile__ (
1462 "movd %0, %%mm1" // %0
1470 Writes the current value of 64-bit MMX Register #2 (MM2).
1472 Writes the current value of MM2. This function is only available on IA32 and
1475 @param Value The 64-bit value to write to MM2.
1484 __asm__
__volatile__ (
1485 "movd %0, %%mm2" // %0
1493 Writes the current value of 64-bit MMX Register #3 (MM3).
1495 Writes the current value of MM3. This function is only available on IA32 and
1498 @param Value The 64-bit value to write to MM3.
1507 __asm__
__volatile__ (
1508 "movd %0, %%mm3" // %0
1516 Writes the current value of 64-bit MMX Register #4 (MM4).
1518 Writes the current value of MM4. This function is only available on IA32 and
1521 @param Value The 64-bit value to write to MM4.
1530 __asm__
__volatile__ (
1531 "movd %0, %%mm4" // %0
1539 Writes the current value of 64-bit MMX Register #5 (MM5).
1541 Writes the current value of MM5. This function is only available on IA32 and
1544 @param Value The 64-bit value to write to MM5.
1553 __asm__
__volatile__ (
1554 "movd %0, %%mm5" // %0
1562 Writes the current value of 64-bit MMX Register #6 (MM6).
1564 Writes the current value of MM6. This function is only available on IA32 and
1567 @param Value The 64-bit value to write to MM6.
1576 __asm__
__volatile__ (
1577 "movd %0, %%mm6" // %0
1585 Writes the current value of 64-bit MMX Register #7 (MM7).
1587 Writes the current value of MM7. This function is only available on IA32 and
1590 @param Value The 64-bit value to write to MM7.
1599 __asm__
__volatile__ (
1600 "movd %0, %%mm7" // %0
1608 Reads the current value of Time Stamp Counter (TSC).
1610 Reads and returns the current value of TSC. This function is only available
1613 @return The current value of TSC
1625 __asm__
__volatile__ (
1631 return (((UINT64
)HiData
) << 32) | LowData
;
1636 Reads the current value of a Performance Counter (PMC).
1638 Reads and returns the current value of performance counter specified by
1639 Index. This function is only available on IA-32 and X64.
1641 @param Index The 32-bit Performance Counter index to read.
1643 @return The value of the PMC specified by Index.
1655 __asm__
__volatile__ (
1662 return (((UINT64
)HiData
) << 32) | LowData
;
1667 Sets up a monitor buffer that is used by AsmMwait().
1669 Executes a MONITOR instruction with the register state specified by Eax, Ecx
1670 and Edx. Returns Eax. This function is only available on IA-32 and X64.
1672 @param Eax The value to load into EAX or RAX before executing the MONITOR
1674 @param Ecx The value to load into ECX or RCX before executing the MONITOR
1676 @param Edx The value to load into EDX or RDX before executing the MONITOR
1690 __asm__
__volatile__ (
1703 Executes an MWAIT instruction.
1705 Executes an MWAIT instruction with the register state specified by Eax and
1706 Ecx. Returns Eax. This function is only available on IA-32 and X64.
1708 @param Eax The value to load into EAX or RAX before executing the MONITOR
1710 @param Ecx The value to load into ECX or RCX before executing the MONITOR
1723 __asm__
__volatile__ (
1735 Executes a WBINVD instruction.
1737 Executes a WBINVD instruction. This function is only available on IA-32 and
1747 __asm__
__volatile__ ("wbinvd":::"memory");
1752 Executes a INVD instruction.
1754 Executes a INVD instruction. This function is only available on IA-32 and
1764 __asm__
__volatile__ ("invd":::"memory");
1770 Flushes a cache line from all the instruction and data caches within the
1771 coherency domain of the CPU.
1773 Flushed the cache line specified by LinearAddress, and returns LinearAddress.
1774 This function is only available on IA-32 and X64.
1776 @param LinearAddress The address of the cache line to flush. If the CPU is
1777 in a physical addressing mode, then LinearAddress is a
1778 physical address. If the CPU is in a virtual
1779 addressing mode, then LinearAddress is a virtual
1782 @return LinearAddress
1787 IN VOID
*LinearAddress
1790 __asm__
__volatile__ (
1793 : "r" (LinearAddress
)
1797 return LinearAddress
;