]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/Ia32/GccInline.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdePkg / Library / BaseLib / Ia32 / GccInline.c
CommitLineData
cf683fed 1/** @file\r
2 GCC inline implementation of BaseLib processor specific functions.\r
9095d37b 3\r
d3c9e40a 4 Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>\r
c9b34b8c 5 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
9344f092 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
cf683fed 7\r
8**/\r
9\r
cf683fed 10#include "BaseLibInternals.h"\r
11\r
cf683fed 12/**\r
d3c9e40a 13 Used to serialize load and store operations.\r
cf683fed 14\r
d3c9e40a
MK
15 All loads and stores that proceed calls to this function are guaranteed to be\r
16 globally visible when this function returns.\r
cf683fed 17\r
18**/\r
19VOID\r
20EFIAPI\r
d3c9e40a
MK
21MemoryFence (\r
22 VOID\r
cf683fed 23 )\r
24{\r
d3c9e40a
MK
25 // This is a little bit of overkill and it is more about the compiler that it is\r
26 // actually processor synchronization. This is like the _ReadWriteBarrier\r
27 // Microsoft specific intrinsic\r
28 __asm__ __volatile__ ("":::"memory");\r
cf683fed 29}\r
30\r
cf683fed 31/**\r
d3c9e40a 32 Requests CPU to pause for a short period of time.\r
cf683fed 33\r
d3c9e40a
MK
34 Requests CPU to pause for a short period of time. Typically used in MP\r
35 systems to prevent memory starvation while waiting for a spin lock.\r
cf683fed 36\r
37**/\r
38VOID\r
39EFIAPI\r
d3c9e40a
MK
40CpuPause (\r
41 VOID\r
cf683fed 42 )\r
43{\r
d3c9e40a 44 __asm__ __volatile__ ("pause");\r
cf683fed 45}\r
46\r
cf683fed 47/**\r
d3c9e40a 48 Generates a breakpoint on the CPU.\r
cf683fed 49\r
d3c9e40a
MK
50 Generates a breakpoint on the CPU. The breakpoint must be implemented such\r
51 that code can resume normal execution after the breakpoint.\r
cf683fed 52\r
53**/\r
54VOID\r
55EFIAPI\r
d3c9e40a
MK
56CpuBreakpoint (\r
57 VOID\r
cf683fed 58 )\r
59{\r
d3c9e40a 60 __asm__ __volatile__ ("int $3");\r
cf683fed 61}\r
62\r
cf683fed 63/**\r
d3c9e40a 64 Reads the current value of the EFLAGS register.\r
cf683fed 65\r
d3c9e40a
MK
66 Reads and returns the current value of the EFLAGS register. This function is\r
67 only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a\r
68 64-bit value on X64.\r
cf683fed 69\r
d3c9e40a 70 @return EFLAGS on IA-32 or RFLAGS on X64.\r
cf683fed 71\r
72**/\r
d3c9e40a 73UINTN\r
cf683fed 74EFIAPI\r
d3c9e40a 75AsmReadEflags (\r
cf683fed 76 VOID\r
77 )\r
78{\r
2f88bd3a 79 UINTN Eflags;\r
9095d37b 80\r
cf683fed 81 __asm__ __volatile__ (\r
d3c9e40a
MK
82 "pushfl \n\t"\r
83 "popl %0 "\r
84 : "=r" (Eflags)\r
2f88bd3a 85 );\r
9095d37b 86\r
d3c9e40a 87 return Eflags;\r
cf683fed 88}\r
89\r
cf683fed 90/**\r
91 Save the current floating point/SSE/SSE2 context to a buffer.\r
92\r
93 Saves the current floating point/SSE/SSE2 state to the buffer specified by\r
94 Buffer. Buffer must be aligned on a 16-byte boundary. This function is only\r
95 available on IA-32 and X64.\r
96\r
2fc59a00 97 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.\r
cf683fed 98\r
99**/\r
100VOID\r
101EFIAPI\r
102InternalX86FxSave (\r
2f88bd3a 103 OUT IA32_FX_BUFFER *Buffer\r
cf683fed 104 )\r
105{\r
106 __asm__ __volatile__ (\r
107 "fxsave %0"\r
108 :\r
109 : "m" (*Buffer) // %0\r
2f88bd3a 110 );\r
cf683fed 111}\r
112\r
cf683fed 113/**\r
114 Restores the current floating point/SSE/SSE2 context from a buffer.\r
115\r
116 Restores the current floating point/SSE/SSE2 state from the buffer specified\r
117 by Buffer. Buffer must be aligned on a 16-byte boundary. This function is\r
118 only available on IA-32 and X64.\r
119\r
2fc59a00 120 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.\r
cf683fed 121\r
122**/\r
123VOID\r
124EFIAPI\r
125InternalX86FxRestore (\r
2f88bd3a 126 IN CONST IA32_FX_BUFFER *Buffer\r
cf683fed 127 )\r
128{\r
129 __asm__ __volatile__ (\r
130 "fxrstor %0"\r
131 :\r
132 : "m" (*Buffer) // %0\r
2f88bd3a 133 );\r
cf683fed 134}\r
135\r
cf683fed 136/**\r
137 Reads the current value of 64-bit MMX Register #0 (MM0).\r
138\r
139 Reads and returns the current value of MM0. This function is only available\r
140 on IA-32 and X64.\r
141\r
142 @return The current value of MM0.\r
143\r
144**/\r
145UINT64\r
146EFIAPI\r
147AsmReadMm0 (\r
148 VOID\r
149 )\r
150{\r
151 UINT64 Data;\r
152\r
153 __asm__ __volatile__ (\r
154 "push %%eax \n\t"\r
155 "push %%eax \n\t"\r
156 "movq %%mm0, (%%esp)\n\t"\r
157 "pop %%eax \n\t"\r
158 "pop %%edx \n\t"\r
159 : "=A" (Data) // %0\r
2f88bd3a 160 );\r
9095d37b 161\r
cf683fed 162 return Data;\r
163}\r
164\r
cf683fed 165/**\r
166 Reads the current value of 64-bit MMX Register #1 (MM1).\r
167\r
168 Reads and returns the current value of MM1. This function is only available\r
169 on IA-32 and X64.\r
170\r
171 @return The current value of MM1.\r
172\r
173**/\r
174UINT64\r
175EFIAPI\r
176AsmReadMm1 (\r
177 VOID\r
178 )\r
179{\r
180 UINT64 Data;\r
181\r
182 __asm__ __volatile__ (\r
183 "push %%eax \n\t"\r
184 "push %%eax \n\t"\r
185 "movq %%mm1, (%%esp)\n\t"\r
186 "pop %%eax \n\t"\r
187 "pop %%edx \n\t"\r
188 : "=A" (Data) // %0\r
2f88bd3a 189 );\r
9095d37b 190\r
cf683fed 191 return Data;\r
192}\r
193\r
cf683fed 194/**\r
195 Reads the current value of 64-bit MMX Register #2 (MM2).\r
196\r
197 Reads and returns the current value of MM2. This function is only available\r
198 on IA-32 and X64.\r
199\r
200 @return The current value of MM2.\r
201\r
202**/\r
203UINT64\r
204EFIAPI\r
205AsmReadMm2 (\r
206 VOID\r
207 )\r
208{\r
209 UINT64 Data;\r
210\r
211 __asm__ __volatile__ (\r
212 "push %%eax \n\t"\r
213 "push %%eax \n\t"\r
214 "movq %%mm2, (%%esp)\n\t"\r
215 "pop %%eax \n\t"\r
216 "pop %%edx \n\t"\r
217 : "=A" (Data) // %0\r
2f88bd3a 218 );\r
9095d37b 219\r
cf683fed 220 return Data;\r
221}\r
222\r
cf683fed 223/**\r
224 Reads the current value of 64-bit MMX Register #3 (MM3).\r
225\r
226 Reads and returns the current value of MM3. This function is only available\r
227 on IA-32 and X64.\r
228\r
229 @return The current value of MM3.\r
230\r
231**/\r
232UINT64\r
233EFIAPI\r
234AsmReadMm3 (\r
235 VOID\r
236 )\r
237{\r
238 UINT64 Data;\r
239\r
240 __asm__ __volatile__ (\r
241 "push %%eax \n\t"\r
242 "push %%eax \n\t"\r
243 "movq %%mm3, (%%esp)\n\t"\r
244 "pop %%eax \n\t"\r
245 "pop %%edx \n\t"\r
246 : "=A" (Data) // %0\r
2f88bd3a 247 );\r
9095d37b 248\r
cf683fed 249 return Data;\r
250}\r
251\r
cf683fed 252/**\r
253 Reads the current value of 64-bit MMX Register #4 (MM4).\r
254\r
255 Reads and returns the current value of MM4. This function is only available\r
256 on IA-32 and X64.\r
257\r
258 @return The current value of MM4.\r
259\r
260**/\r
261UINT64\r
262EFIAPI\r
263AsmReadMm4 (\r
264 VOID\r
265 )\r
266{\r
267 UINT64 Data;\r
268\r
269 __asm__ __volatile__ (\r
270 "push %%eax \n\t"\r
271 "push %%eax \n\t"\r
272 "movq %%mm4, (%%esp)\n\t"\r
273 "pop %%eax \n\t"\r
274 "pop %%edx \n\t"\r
275 : "=A" (Data) // %0\r
2f88bd3a 276 );\r
9095d37b 277\r
cf683fed 278 return Data;\r
279}\r
280\r
cf683fed 281/**\r
282 Reads the current value of 64-bit MMX Register #5 (MM5).\r
283\r
284 Reads and returns the current value of MM5. This function is only available\r
285 on IA-32 and X64.\r
286\r
287 @return The current value of MM5.\r
288\r
289**/\r
290UINT64\r
291EFIAPI\r
292AsmReadMm5 (\r
293 VOID\r
294 )\r
295{\r
296 UINT64 Data;\r
297\r
298 __asm__ __volatile__ (\r
299 "push %%eax \n\t"\r
300 "push %%eax \n\t"\r
301 "movq %%mm5, (%%esp)\n\t"\r
302 "pop %%eax \n\t"\r
303 "pop %%edx \n\t"\r
304 : "=A" (Data) // %0\r
2f88bd3a 305 );\r
9095d37b 306\r
cf683fed 307 return Data;\r
308}\r
309\r
cf683fed 310/**\r
311 Reads the current value of 64-bit MMX Register #6 (MM6).\r
312\r
313 Reads and returns the current value of MM6. This function is only available\r
314 on IA-32 and X64.\r
315\r
316 @return The current value of MM6.\r
317\r
318**/\r
319UINT64\r
320EFIAPI\r
321AsmReadMm6 (\r
322 VOID\r
323 )\r
324{\r
325 UINT64 Data;\r
326\r
327 __asm__ __volatile__ (\r
328 "push %%eax \n\t"\r
329 "push %%eax \n\t"\r
330 "movq %%mm6, (%%esp)\n\t"\r
331 "pop %%eax \n\t"\r
332 "pop %%edx \n\t"\r
333 : "=A" (Data) // %0\r
2f88bd3a 334 );\r
9095d37b 335\r
cf683fed 336 return Data;\r
337}\r
338\r
cf683fed 339/**\r
340 Reads the current value of 64-bit MMX Register #7 (MM7).\r
341\r
342 Reads and returns the current value of MM7. This function is only available\r
343 on IA-32 and X64.\r
344\r
345 @return The current value of MM7.\r
346\r
347**/\r
348UINT64\r
349EFIAPI\r
350AsmReadMm7 (\r
351 VOID\r
352 )\r
353{\r
354 UINT64 Data;\r
355\r
356 __asm__ __volatile__ (\r
357 "push %%eax \n\t"\r
358 "push %%eax \n\t"\r
359 "movq %%mm7, (%%esp)\n\t"\r
360 "pop %%eax \n\t"\r
361 "pop %%edx \n\t"\r
362 : "=A" (Data) // %0\r
2f88bd3a 363 );\r
9095d37b 364\r
cf683fed 365 return Data;\r
366}\r
367\r
cf683fed 368/**\r
369 Writes the current value of 64-bit MMX Register #0 (MM0).\r
370\r
371 Writes the current value of MM0. This function is only available on IA32 and\r
372 X64.\r
373\r
374 @param Value The 64-bit value to write to MM0.\r
375\r
376**/\r
377VOID\r
378EFIAPI\r
379AsmWriteMm0 (\r
2f88bd3a 380 IN UINT64 Value\r
cf683fed 381 )\r
382{\r
383 __asm__ __volatile__ (\r
384 "movq %0, %%mm0" // %0\r
9095d37b 385 :\r
cf683fed 386 : "m" (Value)\r
2f88bd3a 387 );\r
cf683fed 388}\r
389\r
cf683fed 390/**\r
391 Writes the current value of 64-bit MMX Register #1 (MM1).\r
392\r
393 Writes the current value of MM1. This function is only available on IA32 and\r
394 X64.\r
395\r
396 @param Value The 64-bit value to write to MM1.\r
397\r
398**/\r
399VOID\r
400EFIAPI\r
401AsmWriteMm1 (\r
2f88bd3a 402 IN UINT64 Value\r
cf683fed 403 )\r
404{\r
405 __asm__ __volatile__ (\r
406 "movq %0, %%mm1" // %0\r
9095d37b 407 :\r
cf683fed 408 : "m" (Value)\r
2f88bd3a 409 );\r
cf683fed 410}\r
411\r
cf683fed 412/**\r
413 Writes the current value of 64-bit MMX Register #2 (MM2).\r
414\r
415 Writes the current value of MM2. This function is only available on IA32 and\r
416 X64.\r
417\r
418 @param Value The 64-bit value to write to MM2.\r
419\r
420**/\r
421VOID\r
422EFIAPI\r
423AsmWriteMm2 (\r
2f88bd3a 424 IN UINT64 Value\r
cf683fed 425 )\r
426{\r
427 __asm__ __volatile__ (\r
428 "movq %0, %%mm2" // %0\r
9095d37b 429 :\r
cf683fed 430 : "m" (Value)\r
2f88bd3a 431 );\r
cf683fed 432}\r
433\r
cf683fed 434/**\r
435 Writes the current value of 64-bit MMX Register #3 (MM3).\r
436\r
437 Writes the current value of MM3. This function is only available on IA32 and\r
438 X64.\r
439\r
440 @param Value The 64-bit value to write to MM3.\r
441\r
442**/\r
443VOID\r
444EFIAPI\r
445AsmWriteMm3 (\r
2f88bd3a 446 IN UINT64 Value\r
cf683fed 447 )\r
448{\r
449 __asm__ __volatile__ (\r
450 "movq %0, %%mm3" // %0\r
9095d37b 451 :\r
cf683fed 452 : "m" (Value)\r
2f88bd3a 453 );\r
cf683fed 454}\r
455\r
cf683fed 456/**\r
457 Writes the current value of 64-bit MMX Register #4 (MM4).\r
458\r
459 Writes the current value of MM4. This function is only available on IA32 and\r
460 X64.\r
461\r
462 @param Value The 64-bit value to write to MM4.\r
463\r
464**/\r
465VOID\r
466EFIAPI\r
467AsmWriteMm4 (\r
2f88bd3a 468 IN UINT64 Value\r
cf683fed 469 )\r
470{\r
471 __asm__ __volatile__ (\r
472 "movq %0, %%mm4" // %0\r
9095d37b 473 :\r
cf683fed 474 : "m" (Value)\r
2f88bd3a 475 );\r
cf683fed 476}\r
477\r
cf683fed 478/**\r
479 Writes the current value of 64-bit MMX Register #5 (MM5).\r
480\r
481 Writes the current value of MM5. This function is only available on IA32 and\r
482 X64.\r
483\r
484 @param Value The 64-bit value to write to MM5.\r
485\r
486**/\r
487VOID\r
488EFIAPI\r
489AsmWriteMm5 (\r
2f88bd3a 490 IN UINT64 Value\r
cf683fed 491 )\r
492{\r
493 __asm__ __volatile__ (\r
494 "movq %0, %%mm5" // %0\r
9095d37b 495 :\r
cf683fed 496 : "m" (Value)\r
2f88bd3a 497 );\r
cf683fed 498}\r
499\r
cf683fed 500/**\r
501 Writes the current value of 64-bit MMX Register #6 (MM6).\r
502\r
503 Writes the current value of MM6. This function is only available on IA32 and\r
504 X64.\r
505\r
506 @param Value The 64-bit value to write to MM6.\r
507\r
508**/\r
509VOID\r
510EFIAPI\r
511AsmWriteMm6 (\r
2f88bd3a 512 IN UINT64 Value\r
cf683fed 513 )\r
514{\r
515 __asm__ __volatile__ (\r
516 "movq %0, %%mm6" // %0\r
9095d37b 517 :\r
cf683fed 518 : "m" (Value)\r
2f88bd3a 519 );\r
cf683fed 520}\r
521\r
cf683fed 522/**\r
523 Writes the current value of 64-bit MMX Register #7 (MM7).\r
524\r
525 Writes the current value of MM7. This function is only available on IA32 and\r
526 X64.\r
527\r
528 @param Value The 64-bit value to write to MM7.\r
529\r
530**/\r
531VOID\r
532EFIAPI\r
533AsmWriteMm7 (\r
2f88bd3a 534 IN UINT64 Value\r
cf683fed 535 )\r
536{\r
537 __asm__ __volatile__ (\r
538 "movq %0, %%mm7" // %0\r
9095d37b 539 :\r
cf683fed 540 : "m" (Value)\r
2f88bd3a 541 );\r
cf683fed 542}\r
543\r
cf683fed 544/**\r
545 Reads the current value of Time Stamp Counter (TSC).\r
546\r
547 Reads and returns the current value of TSC. This function is only available\r
548 on IA-32 and X64.\r
549\r
550 @return The current value of TSC\r
551\r
552**/\r
553UINT64\r
554EFIAPI\r
555AsmReadTsc (\r
556 VOID\r
557 )\r
558{\r
559 UINT64 Data;\r
9095d37b 560\r
cf683fed 561 __asm__ __volatile__ (\r
562 "rdtsc"\r
563 : "=A" (Data)\r
2f88bd3a 564 );\r
9095d37b
LG
565\r
566 return Data;\r
cf683fed 567}\r