]>
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 - 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.
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"
22 Used to serialize load and store operations.
24 All loads and stores that proceed calls to this function are guaranteed to be
25 globally visible when this function returns.
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");
42 Enables CPU interrupts.
44 Enables CPU interrupts.
53 __asm__
__volatile__ ("sti"::: "memory");
58 Disables CPU interrupts.
60 Disables CPU interrupts.
69 __asm__
__volatile__ ("cli"::: "memory");
76 Requests CPU to pause for a short period of time.
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.
88 __asm__
__volatile__ ("pause");
93 Generates a breakpoint on the CPU.
95 Generates a breakpoint on the CPU. The breakpoint must be implemented such
96 that code can resume normal execution after the breakpoint.
105 __asm__
__volatile__ ("int $3");
111 Returns a 64-bit Machine Specific Register(MSR).
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
119 @param Index The 32-bit MSR index to read.
121 @return The value of the MSR identified by Index.
132 __asm__
__volatile__ (
142 Writes a 64-bit value to a Machine Specific Register(MSR), and returns the
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
152 @param Index The 32-bit MSR index to write.
153 @param Value The 64-bit value to write to the MSR.
165 __asm__
__volatile__ (
178 Reads the current value of the EFLAGS register.
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
184 @return EFLAGS on IA-32 or RFLAGS on X64.
195 __asm__
__volatile__ (
207 Reads the current value of the Control Register 0 (CR0).
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
213 @return The value of the Control Register 0 (CR0).
224 __asm__
__volatile__ (
234 Reads the current value of the Control Register 2 (CR2).
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
240 @return The value of the Control Register 2 (CR2).
251 __asm__
__volatile__ (
260 Reads the current value of the Control Register 3 (CR3).
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
266 @return The value of the Control Register 3 (CR3).
277 __asm__
__volatile__ (
287 Reads the current value of the Control Register 4 (CR4).
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
293 @return The value of the Control Register 4 (CR4).
304 __asm__
__volatile__ (
314 Writes a value to Control Register 0 (CR0).
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.
319 @param Cr0 The value to write to CR0.
321 @return The value written to CR0.
330 __asm__
__volatile__ (
340 Writes a value to Control Register 2 (CR2).
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.
345 @param Cr2 The value to write to CR2.
347 @return The value written to CR2.
356 __asm__
__volatile__ (
366 Writes a value to Control Register 3 (CR3).
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.
371 @param Cr3 The value to write to CR3.
373 @return The value written to CR3.
382 __asm__
__volatile__ (
392 Writes a value to Control Register 4 (CR4).
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.
397 @param Cr4 The value to write to CR4.
399 @return The value written to CR4.
408 __asm__
__volatile__ (
418 Reads the current value of Debug Register 0 (DR0).
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
424 @return The value of Debug Register 0 (DR0).
435 __asm__
__volatile__ (
445 Reads the current value of Debug Register 1 (DR1).
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
451 @return The value of Debug Register 1 (DR1).
462 __asm__
__volatile__ (
472 Reads the current value of Debug Register 2 (DR2).
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
478 @return The value of Debug Register 2 (DR2).
489 __asm__
__volatile__ (
499 Reads the current value of Debug Register 3 (DR3).
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
505 @return The value of Debug Register 3 (DR3).
516 __asm__
__volatile__ (
526 Reads the current value of Debug Register 4 (DR4).
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
532 @return The value of Debug Register 4 (DR4).
543 __asm__
__volatile__ (
553 Reads the current value of Debug Register 5 (DR5).
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
559 @return The value of Debug Register 5 (DR5).
570 __asm__
__volatile__ (
580 Reads the current value of Debug Register 6 (DR6).
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
586 @return The value of Debug Register 6 (DR6).
597 __asm__
__volatile__ (
607 Reads the current value of Debug Register 7 (DR7).
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
613 @return The value of Debug Register 7 (DR7).
624 __asm__
__volatile__ (
634 Writes a value to Debug Register 0 (DR0).
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.
639 @param Dr0 The value to write to Dr0.
641 @return The value written to Debug Register 0 (DR0).
650 __asm__
__volatile__ (
660 Writes a value to Debug Register 1 (DR1).
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.
665 @param Dr1 The value to write to Dr1.
667 @return The value written to Debug Register 1 (DR1).
676 __asm__
__volatile__ (
686 Writes a value to Debug Register 2 (DR2).
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.
691 @param Dr2 The value to write to Dr2.
693 @return The value written to Debug Register 2 (DR2).
702 __asm__
__volatile__ (
712 Writes a value to Debug Register 3 (DR3).
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.
717 @param Dr3 The value to write to Dr3.
719 @return The value written to Debug Register 3 (DR3).
728 __asm__
__volatile__ (
738 Writes a value to Debug Register 4 (DR4).
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.
743 @param Dr4 The value to write to Dr4.
745 @return The value written to Debug Register 4 (DR4).
754 __asm__
__volatile__ (
764 Writes a value to Debug Register 5 (DR5).
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.
769 @param Dr5 The value to write to Dr5.
771 @return The value written to Debug Register 5 (DR5).
780 __asm__
__volatile__ (
790 Writes a value to Debug Register 6 (DR6).
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.
795 @param Dr6 The value to write to Dr6.
797 @return The value written to Debug Register 6 (DR6).
806 __asm__
__volatile__ (
816 Writes a value to Debug Register 7 (DR7).
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.
821 @param Dr7 The value to write to Dr7.
823 @return The value written to Debug Register 7 (DR7).
832 __asm__
__volatile__ (
842 Reads the current value of Code Segment Register (CS).
844 Reads and returns the current value of CS. This function is only available on
847 @return The current value of CS.
858 __asm__
__volatile__ (
868 Reads the current value of Data Segment Register (DS).
870 Reads and returns the current value of DS. This function is only available on
873 @return The current value of DS.
884 __asm__
__volatile__ (
894 Reads the current value of Extra Segment Register (ES).
896 Reads and returns the current value of ES. This function is only available on
899 @return The current value of ES.
910 __asm__
__volatile__ (
920 Reads the current value of FS Data Segment Register (FS).
922 Reads and returns the current value of FS. This function is only available on
925 @return The current value of FS.
936 __asm__
__volatile__ (
946 Reads the current value of GS Data Segment Register (GS).
948 Reads and returns the current value of GS. This function is only available on
951 @return The current value of GS.
962 __asm__
__volatile__ (
972 Reads the current value of Stack Segment Register (SS).
974 Reads and returns the current value of SS. This function is only available on
977 @return The current value of SS.
988 __asm__
__volatile__ (
998 Reads the current value of Task Register (TR).
1000 Reads and returns the current value of TR. This function is only available on
1003 @return The current value of TR.
1014 __asm__
__volatile__ (
1024 Reads the current Global Descriptor Table Register(GDTR) descriptor.
1026 Reads and returns the current GDTR descriptor and returns it in Gdtr. This
1027 function is only available on IA-32 and X64.
1029 @param Gdtr The pointer to a GDTR descriptor.
1034 InternalX86ReadGdtr (
1035 OUT IA32_DESCRIPTOR
*Gdtr
1038 __asm__
__volatile__ (
1046 Writes the current Global Descriptor Table Register (GDTR) descriptor.
1048 Writes and the current GDTR descriptor specified by Gdtr. This function is
1049 only available on IA-32 and X64.
1051 @param Gdtr The pointer to a GDTR descriptor.
1056 InternalX86WriteGdtr (
1057 IN CONST IA32_DESCRIPTOR
*Gdtr
1060 __asm__
__volatile__ (
1070 Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.
1072 Reads and returns the current IDTR descriptor and returns it in Idtr. This
1073 function is only available on IA-32 and X64.
1075 @param Idtr The pointer to a IDTR descriptor.
1080 InternalX86ReadIdtr (
1081 OUT IA32_DESCRIPTOR
*Idtr
1084 __asm__
__volatile__ (
1092 Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.
1094 Writes the current IDTR descriptor and returns it in Idtr. This function is
1095 only available on IA-32 and X64.
1097 @param Idtr The pointer to a IDTR descriptor.
1102 InternalX86WriteIdtr (
1103 IN CONST IA32_DESCRIPTOR
*Idtr
1106 __asm__
__volatile__ (
1115 Reads the current Local Descriptor Table Register(LDTR) selector.
1117 Reads and returns the current 16-bit LDTR descriptor value. This function is
1118 only available on IA-32 and X64.
1120 @return The current selector of LDT.
1131 __asm__
__volatile__ (
1141 Writes the current Local Descriptor Table Register (GDTR) selector.
1143 Writes and the current LDTR descriptor specified by Ldtr. This function is
1144 only available on IA-32 and X64.
1146 @param Ldtr 16-bit LDTR selector value.
1155 __asm__
__volatile__ (
1164 Save the current floating point/SSE/SSE2 context to a buffer.
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.
1170 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
1176 OUT IA32_FX_BUFFER
*Buffer
1179 __asm__
__volatile__ (
1182 : "m" (*Buffer
) // %0
1188 Restores the current floating point/SSE/SSE2 context from a buffer.
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.
1194 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
1199 InternalX86FxRestore (
1200 IN CONST IA32_FX_BUFFER
*Buffer
1203 __asm__
__volatile__ (
1206 : "m" (*Buffer
) // %0
1212 Reads the current value of 64-bit MMX Register #0 (MM0).
1214 Reads and returns the current value of MM0. This function is only available
1217 @return The current value of MM0.
1228 __asm__
__volatile__ (
1231 "movq %%mm0, (%%esp)\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__ (
1261 "movq %%mm1, (%%esp)\n\t"
1272 Reads the current value of 64-bit MMX Register #2 (MM2).
1274 Reads and returns the current value of MM2. This function is only available
1277 @return The current value of MM2.
1288 __asm__
__volatile__ (
1291 "movq %%mm2, (%%esp)\n\t"
1302 Reads the current value of 64-bit MMX Register #3 (MM3).
1304 Reads and returns the current value of MM3. This function is only available
1307 @return The current value of MM3.
1318 __asm__
__volatile__ (
1321 "movq %%mm3, (%%esp)\n\t"
1332 Reads the current value of 64-bit MMX Register #4 (MM4).
1334 Reads and returns the current value of MM4. This function is only available
1337 @return The current value of MM4.
1348 __asm__
__volatile__ (
1351 "movq %%mm4, (%%esp)\n\t"
1362 Reads the current value of 64-bit MMX Register #5 (MM5).
1364 Reads and returns the current value of MM5. This function is only available
1367 @return The current value of MM5.
1378 __asm__
__volatile__ (
1381 "movq %%mm5, (%%esp)\n\t"
1392 Reads the current value of 64-bit MMX Register #6 (MM6).
1394 Reads and returns the current value of MM6. This function is only available
1397 @return The current value of MM6.
1408 __asm__
__volatile__ (
1411 "movq %%mm6, (%%esp)\n\t"
1422 Reads the current value of 64-bit MMX Register #7 (MM7).
1424 Reads and returns the current value of MM7. This function is only available
1427 @return The current value of MM7.
1438 __asm__
__volatile__ (
1441 "movq %%mm7, (%%esp)\n\t"
1452 Writes the current value of 64-bit MMX Register #0 (MM0).
1454 Writes the current value of MM0. This function is only available on IA32 and
1457 @param Value The 64-bit value to write to MM0.
1466 __asm__
__volatile__ (
1467 "movq %0, %%mm0" // %0
1475 Writes the current value of 64-bit MMX Register #1 (MM1).
1477 Writes the current value of MM1. This function is only available on IA32 and
1480 @param Value The 64-bit value to write to MM1.
1489 __asm__
__volatile__ (
1490 "movq %0, %%mm1" // %0
1498 Writes the current value of 64-bit MMX Register #2 (MM2).
1500 Writes the current value of MM2. This function is only available on IA32 and
1503 @param Value The 64-bit value to write to MM2.
1512 __asm__
__volatile__ (
1513 "movq %0, %%mm2" // %0
1521 Writes the current value of 64-bit MMX Register #3 (MM3).
1523 Writes the current value of MM3. This function is only available on IA32 and
1526 @param Value The 64-bit value to write to MM3.
1535 __asm__
__volatile__ (
1536 "movq %0, %%mm3" // %0
1544 Writes the current value of 64-bit MMX Register #4 (MM4).
1546 Writes the current value of MM4. This function is only available on IA32 and
1549 @param Value The 64-bit value to write to MM4.
1558 __asm__
__volatile__ (
1559 "movq %0, %%mm4" // %0
1567 Writes the current value of 64-bit MMX Register #5 (MM5).
1569 Writes the current value of MM5. This function is only available on IA32 and
1572 @param Value The 64-bit value to write to MM5.
1581 __asm__
__volatile__ (
1582 "movq %0, %%mm5" // %0
1590 Writes the current value of 64-bit MMX Register #6 (MM6).
1592 Writes the current value of MM6. This function is only available on IA32 and
1595 @param Value The 64-bit value to write to MM6.
1604 __asm__
__volatile__ (
1605 "movq %0, %%mm6" // %0
1613 Writes the current value of 64-bit MMX Register #7 (MM7).
1615 Writes the current value of MM7. This function is only available on IA32 and
1618 @param Value The 64-bit value to write to MM7.
1627 __asm__
__volatile__ (
1628 "movq %0, %%mm7" // %0
1636 Reads the current value of Time Stamp Counter (TSC).
1638 Reads and returns the current value of TSC. This function is only available
1641 @return The current value of TSC
1652 __asm__
__volatile__ (
1662 Reads the current value of a Performance Counter (PMC).
1664 Reads and returns the current value of performance counter specified by
1665 Index. This function is only available on IA-32 and X64.
1667 @param Index The 32-bit Performance Counter index to read.
1669 @return The value of the PMC specified by Index.
1680 __asm__
__volatile__ (
1693 Executes a WBINVD instruction.
1695 Executes a WBINVD instruction. This function is only available on IA-32 and
1705 __asm__
__volatile__ ("wbinvd":::"memory");
1710 Executes a INVD instruction.
1712 Executes a INVD instruction. This function is only available on IA-32 and
1722 __asm__
__volatile__ ("invd":::"memory");
1728 Flushes a cache line from all the instruction and data caches within the
1729 coherency domain of the CPU.
1731 Flushed the cache line specified by LinearAddress, and returns LinearAddress.
1732 This function is only available on IA-32 and X64.
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
1740 @return LinearAddress
1745 IN VOID
*LinearAddress
1751 // If the CPU does not support CLFLUSH instruction,
1752 // then promote flush range to flush entire cache.
1754 AsmCpuid (0x01, NULL
, NULL
, NULL
, &RegEdx
);
1755 if ((RegEdx
& BIT19
) == 0) {
1756 __asm__
__volatile__ ("wbinvd":::"memory");
1757 return LinearAddress
;
1761 __asm__
__volatile__ (
1763 : "+a" (LinearAddress
)
1768 return LinearAddress
;