]>
git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/Ia32/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"
16 Used to serialize load and store operations.
18 All loads and stores that proceed calls to this function are guaranteed to be
19 globally visible when this function returns.
28 // This is a little bit of overkill and it is more about the compiler that it is
29 // actually processor synchronization. This is like the _ReadWriteBarrier
30 // Microsoft specific intrinsic
31 __asm__
__volatile__ ("":::"memory");
36 Enables CPU interrupts.
38 Enables CPU interrupts.
47 __asm__
__volatile__ ("sti"::: "memory");
52 Disables CPU interrupts.
54 Disables CPU interrupts.
63 __asm__
__volatile__ ("cli"::: "memory");
70 Requests CPU to pause for a short period of time.
72 Requests CPU to pause for a short period of time. Typically used in MP
73 systems to prevent memory starvation while waiting for a spin lock.
82 __asm__
__volatile__ ("pause");
87 Generates a breakpoint on the CPU.
89 Generates a breakpoint on the CPU. The breakpoint must be implemented such
90 that code can resume normal execution after the breakpoint.
99 __asm__
__volatile__ ("int $3");
105 Returns a 64-bit Machine Specific Register(MSR).
107 Reads and returns the 64-bit MSR specified by Index. No parameter checking is
108 performed on Index, and some Index values may cause CPU exceptions. The
109 caller must either guarantee that Index is valid, or the caller must set up
110 exception handlers to catch the exceptions. This function is only available
113 @param Index The 32-bit MSR index to read.
115 @return The value of the MSR identified by Index.
126 __asm__
__volatile__ (
136 Writes a 64-bit value to a Machine Specific Register(MSR), and returns the
139 Writes the 64-bit value specified by Value to the MSR specified by Index. The
140 64-bit value written to the MSR is returned. No parameter checking is
141 performed on Index or Value, and some of these may cause CPU exceptions. The
142 caller must either guarantee that Index and Value are valid, or the caller
143 must establish proper exception handlers. This function is only available on
146 @param Index The 32-bit MSR index to write.
147 @param Value The 64-bit value to write to the MSR.
159 __asm__
__volatile__ (
172 Reads the current value of the EFLAGS register.
174 Reads and returns the current value of the EFLAGS register. This function is
175 only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a
178 @return EFLAGS on IA-32 or RFLAGS on X64.
189 __asm__
__volatile__ (
201 Reads the current value of the Control Register 0 (CR0).
203 Reads and returns the current value of CR0. This function is only available
204 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
207 @return The value of the Control Register 0 (CR0).
218 __asm__
__volatile__ (
228 Reads the current value of the Control Register 2 (CR2).
230 Reads and returns the current value of CR2. This function is only available
231 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
234 @return The value of the Control Register 2 (CR2).
245 __asm__
__volatile__ (
254 Reads the current value of the Control Register 3 (CR3).
256 Reads and returns the current value of CR3. This function is only available
257 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
260 @return The value of the Control Register 3 (CR3).
271 __asm__
__volatile__ (
281 Reads the current value of the Control Register 4 (CR4).
283 Reads and returns the current value of CR4. This function is only available
284 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
287 @return The value of the Control Register 4 (CR4).
298 __asm__
__volatile__ (
308 Writes a value to Control Register 0 (CR0).
310 Writes and returns a new value to CR0. This function is only available on
311 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
313 @param Cr0 The value to write to CR0.
315 @return The value written to CR0.
324 __asm__
__volatile__ (
334 Writes a value to Control Register 2 (CR2).
336 Writes and returns a new value to CR2. This function is only available on
337 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
339 @param Cr2 The value to write to CR2.
341 @return The value written to CR2.
350 __asm__
__volatile__ (
360 Writes a value to Control Register 3 (CR3).
362 Writes and returns a new value to CR3. This function is only available on
363 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
365 @param Cr3 The value to write to CR3.
367 @return The value written to CR3.
376 __asm__
__volatile__ (
386 Writes a value to Control Register 4 (CR4).
388 Writes and returns a new value to CR4. This function is only available on
389 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
391 @param Cr4 The value to write to CR4.
393 @return The value written to CR4.
402 __asm__
__volatile__ (
412 Reads the current value of Debug Register 0 (DR0).
414 Reads and returns the current value of DR0. This function is only available
415 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
418 @return The value of Debug Register 0 (DR0).
429 __asm__
__volatile__ (
439 Reads the current value of Debug Register 1 (DR1).
441 Reads and returns the current value of DR1. This function is only available
442 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
445 @return The value of Debug Register 1 (DR1).
456 __asm__
__volatile__ (
466 Reads the current value of Debug Register 2 (DR2).
468 Reads and returns the current value of DR2. This function is only available
469 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
472 @return The value of Debug Register 2 (DR2).
483 __asm__
__volatile__ (
493 Reads the current value of Debug Register 3 (DR3).
495 Reads and returns the current value of DR3. This function is only available
496 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
499 @return The value of Debug Register 3 (DR3).
510 __asm__
__volatile__ (
520 Reads the current value of Debug Register 4 (DR4).
522 Reads and returns the current value of DR4. This function is only available
523 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
526 @return The value of Debug Register 4 (DR4).
537 __asm__
__volatile__ (
547 Reads the current value of Debug Register 5 (DR5).
549 Reads and returns the current value of DR5. This function is only available
550 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
553 @return The value of Debug Register 5 (DR5).
564 __asm__
__volatile__ (
574 Reads the current value of Debug Register 6 (DR6).
576 Reads and returns the current value of DR6. This function is only available
577 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
580 @return The value of Debug Register 6 (DR6).
591 __asm__
__volatile__ (
601 Reads the current value of Debug Register 7 (DR7).
603 Reads and returns the current value of DR7. This function is only available
604 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
607 @return The value of Debug Register 7 (DR7).
618 __asm__
__volatile__ (
628 Writes a value to Debug Register 0 (DR0).
630 Writes and returns a new value to DR0. This function is only available on
631 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
633 @param Dr0 The value to write to Dr0.
635 @return The value written to Debug Register 0 (DR0).
644 __asm__
__volatile__ (
654 Writes a value to Debug Register 1 (DR1).
656 Writes and returns a new value to DR1. This function is only available on
657 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
659 @param Dr1 The value to write to Dr1.
661 @return The value written to Debug Register 1 (DR1).
670 __asm__
__volatile__ (
680 Writes a value to Debug Register 2 (DR2).
682 Writes and returns a new value to DR2. This function is only available on
683 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
685 @param Dr2 The value to write to Dr2.
687 @return The value written to Debug Register 2 (DR2).
696 __asm__
__volatile__ (
706 Writes a value to Debug Register 3 (DR3).
708 Writes and returns a new value to DR3. This function is only available on
709 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
711 @param Dr3 The value to write to Dr3.
713 @return The value written to Debug Register 3 (DR3).
722 __asm__
__volatile__ (
732 Writes a value to Debug Register 4 (DR4).
734 Writes and returns a new value to DR4. This function is only available on
735 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
737 @param Dr4 The value to write to Dr4.
739 @return The value written to Debug Register 4 (DR4).
748 __asm__
__volatile__ (
758 Writes a value to Debug Register 5 (DR5).
760 Writes and returns a new value to DR5. This function is only available on
761 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
763 @param Dr5 The value to write to Dr5.
765 @return The value written to Debug Register 5 (DR5).
774 __asm__
__volatile__ (
784 Writes a value to Debug Register 6 (DR6).
786 Writes and returns a new value to DR6. This function is only available on
787 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
789 @param Dr6 The value to write to Dr6.
791 @return The value written to Debug Register 6 (DR6).
800 __asm__
__volatile__ (
810 Writes a value to Debug Register 7 (DR7).
812 Writes and returns a new value to DR7. This function is only available on
813 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
815 @param Dr7 The value to write to Dr7.
817 @return The value written to Debug Register 7 (DR7).
826 __asm__
__volatile__ (
836 Reads the current value of Code Segment Register (CS).
838 Reads and returns the current value of CS. This function is only available on
841 @return The current value of CS.
852 __asm__
__volatile__ (
862 Reads the current value of Data Segment Register (DS).
864 Reads and returns the current value of DS. This function is only available on
867 @return The current value of DS.
878 __asm__
__volatile__ (
888 Reads the current value of Extra Segment Register (ES).
890 Reads and returns the current value of ES. This function is only available on
893 @return The current value of ES.
904 __asm__
__volatile__ (
914 Reads the current value of FS Data Segment Register (FS).
916 Reads and returns the current value of FS. This function is only available on
919 @return The current value of FS.
930 __asm__
__volatile__ (
940 Reads the current value of GS Data Segment Register (GS).
942 Reads and returns the current value of GS. This function is only available on
945 @return The current value of GS.
956 __asm__
__volatile__ (
966 Reads the current value of Stack Segment Register (SS).
968 Reads and returns the current value of SS. This function is only available on
971 @return The current value of SS.
982 __asm__
__volatile__ (
992 Reads the current value of Task Register (TR).
994 Reads and returns the current value of TR. This function is only available on
997 @return The current value of TR.
1008 __asm__
__volatile__ (
1018 Reads the current Global Descriptor Table Register(GDTR) descriptor.
1020 Reads and returns the current GDTR descriptor and returns it in Gdtr. This
1021 function is only available on IA-32 and X64.
1023 @param Gdtr The pointer to a GDTR descriptor.
1028 InternalX86ReadGdtr (
1029 OUT IA32_DESCRIPTOR
*Gdtr
1032 __asm__
__volatile__ (
1040 Writes the current Global Descriptor Table Register (GDTR) descriptor.
1042 Writes and the current GDTR descriptor specified by Gdtr. This function is
1043 only available on IA-32 and X64.
1045 @param Gdtr The pointer to a GDTR descriptor.
1050 InternalX86WriteGdtr (
1051 IN CONST IA32_DESCRIPTOR
*Gdtr
1054 __asm__
__volatile__ (
1064 Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.
1066 Reads and returns the current IDTR descriptor and returns it in Idtr. This
1067 function is only available on IA-32 and X64.
1069 @param Idtr The pointer to a IDTR descriptor.
1074 InternalX86ReadIdtr (
1075 OUT IA32_DESCRIPTOR
*Idtr
1078 __asm__
__volatile__ (
1086 Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.
1088 Writes the current IDTR descriptor and returns it in Idtr. This function is
1089 only available on IA-32 and X64.
1091 @param Idtr The pointer to a IDTR descriptor.
1096 InternalX86WriteIdtr (
1097 IN CONST IA32_DESCRIPTOR
*Idtr
1100 __asm__
__volatile__ (
1109 Reads the current Local Descriptor Table Register(LDTR) selector.
1111 Reads and returns the current 16-bit LDTR descriptor value. This function is
1112 only available on IA-32 and X64.
1114 @return The current selector of LDT.
1125 __asm__
__volatile__ (
1135 Writes the current Local Descriptor Table Register (GDTR) selector.
1137 Writes and the current LDTR descriptor specified by Ldtr. This function is
1138 only available on IA-32 and X64.
1140 @param Ldtr 16-bit LDTR selector value.
1149 __asm__
__volatile__ (
1158 Save the current floating point/SSE/SSE2 context to a buffer.
1160 Saves the current floating point/SSE/SSE2 state to the buffer specified by
1161 Buffer. Buffer must be aligned on a 16-byte boundary. This function is only
1162 available on IA-32 and X64.
1164 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
1170 OUT IA32_FX_BUFFER
*Buffer
1173 __asm__
__volatile__ (
1176 : "m" (*Buffer
) // %0
1182 Restores the current floating point/SSE/SSE2 context from a buffer.
1184 Restores the current floating point/SSE/SSE2 state from the buffer specified
1185 by Buffer. Buffer must be aligned on a 16-byte boundary. This function is
1186 only available on IA-32 and X64.
1188 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
1193 InternalX86FxRestore (
1194 IN CONST IA32_FX_BUFFER
*Buffer
1197 __asm__
__volatile__ (
1200 : "m" (*Buffer
) // %0
1206 Reads the current value of 64-bit MMX Register #0 (MM0).
1208 Reads and returns the current value of MM0. This function is only available
1211 @return The current value of MM0.
1222 __asm__
__volatile__ (
1225 "movq %%mm0, (%%esp)\n\t"
1236 Reads the current value of 64-bit MMX Register #1 (MM1).
1238 Reads and returns the current value of MM1. This function is only available
1241 @return The current value of MM1.
1252 __asm__
__volatile__ (
1255 "movq %%mm1, (%%esp)\n\t"
1266 Reads the current value of 64-bit MMX Register #2 (MM2).
1268 Reads and returns the current value of MM2. This function is only available
1271 @return The current value of MM2.
1282 __asm__
__volatile__ (
1285 "movq %%mm2, (%%esp)\n\t"
1296 Reads the current value of 64-bit MMX Register #3 (MM3).
1298 Reads and returns the current value of MM3. This function is only available
1301 @return The current value of MM3.
1312 __asm__
__volatile__ (
1315 "movq %%mm3, (%%esp)\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__ (
1345 "movq %%mm4, (%%esp)\n\t"
1356 Reads the current value of 64-bit MMX Register #5 (MM5).
1358 Reads and returns the current value of MM5. This function is only available
1361 @return The current value of MM5.
1372 __asm__
__volatile__ (
1375 "movq %%mm5, (%%esp)\n\t"
1386 Reads the current value of 64-bit MMX Register #6 (MM6).
1388 Reads and returns the current value of MM6. This function is only available
1391 @return The current value of MM6.
1402 __asm__
__volatile__ (
1405 "movq %%mm6, (%%esp)\n\t"
1416 Reads the current value of 64-bit MMX Register #7 (MM7).
1418 Reads and returns the current value of MM7. This function is only available
1421 @return The current value of MM7.
1432 __asm__
__volatile__ (
1435 "movq %%mm7, (%%esp)\n\t"
1446 Writes the current value of 64-bit MMX Register #0 (MM0).
1448 Writes the current value of MM0. This function is only available on IA32 and
1451 @param Value The 64-bit value to write to MM0.
1460 __asm__
__volatile__ (
1461 "movq %0, %%mm0" // %0
1469 Writes the current value of 64-bit MMX Register #1 (MM1).
1471 Writes the current value of MM1. This function is only available on IA32 and
1474 @param Value The 64-bit value to write to MM1.
1483 __asm__
__volatile__ (
1484 "movq %0, %%mm1" // %0
1492 Writes the current value of 64-bit MMX Register #2 (MM2).
1494 Writes the current value of MM2. This function is only available on IA32 and
1497 @param Value The 64-bit value to write to MM2.
1506 __asm__
__volatile__ (
1507 "movq %0, %%mm2" // %0
1515 Writes the current value of 64-bit MMX Register #3 (MM3).
1517 Writes the current value of MM3. This function is only available on IA32 and
1520 @param Value The 64-bit value to write to MM3.
1529 __asm__
__volatile__ (
1530 "movq %0, %%mm3" // %0
1538 Writes the current value of 64-bit MMX Register #4 (MM4).
1540 Writes the current value of MM4. This function is only available on IA32 and
1543 @param Value The 64-bit value to write to MM4.
1552 __asm__
__volatile__ (
1553 "movq %0, %%mm4" // %0
1561 Writes the current value of 64-bit MMX Register #5 (MM5).
1563 Writes the current value of MM5. This function is only available on IA32 and
1566 @param Value The 64-bit value to write to MM5.
1575 __asm__
__volatile__ (
1576 "movq %0, %%mm5" // %0
1584 Writes the current value of 64-bit MMX Register #6 (MM6).
1586 Writes the current value of MM6. This function is only available on IA32 and
1589 @param Value The 64-bit value to write to MM6.
1598 __asm__
__volatile__ (
1599 "movq %0, %%mm6" // %0
1607 Writes the current value of 64-bit MMX Register #7 (MM7).
1609 Writes the current value of MM7. This function is only available on IA32 and
1612 @param Value The 64-bit value to write to MM7.
1621 __asm__
__volatile__ (
1622 "movq %0, %%mm7" // %0
1630 Reads the current value of Time Stamp Counter (TSC).
1632 Reads and returns the current value of TSC. This function is only available
1635 @return The current value of TSC
1646 __asm__
__volatile__ (
1656 Reads the current value of a Performance Counter (PMC).
1658 Reads and returns the current value of performance counter specified by
1659 Index. This function is only available on IA-32 and X64.
1661 @param Index The 32-bit Performance Counter index to read.
1663 @return The value of the PMC specified by Index.
1674 __asm__
__volatile__ (
1687 Executes a WBINVD instruction.
1689 Executes a WBINVD instruction. This function is only available on IA-32 and
1699 __asm__
__volatile__ ("wbinvd":::"memory");
1704 Executes a INVD instruction.
1706 Executes a INVD instruction. This function is only available on IA-32 and
1716 __asm__
__volatile__ ("invd":::"memory");
1722 Flushes a cache line from all the instruction and data caches within the
1723 coherency domain of the CPU.
1725 Flushed the cache line specified by LinearAddress, and returns LinearAddress.
1726 This function is only available on IA-32 and X64.
1728 @param LinearAddress The address of the cache line to flush. If the CPU is
1729 in a physical addressing mode, then LinearAddress is a
1730 physical address. If the CPU is in a virtual
1731 addressing mode, then LinearAddress is a virtual
1734 @return LinearAddress
1739 IN VOID
*LinearAddress
1745 // If the CPU does not support CLFLUSH instruction,
1746 // then promote flush range to flush entire cache.
1748 AsmCpuid (0x01, NULL
, NULL
, NULL
, &RegEdx
);
1749 if ((RegEdx
& BIT19
) == 0) {
1750 __asm__
__volatile__ ("wbinvd":::"memory");
1751 return LinearAddress
;
1755 __asm__
__volatile__ (
1757 : "+a" (LinearAddress
)
1762 return LinearAddress
;