]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/X64/GccInline.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdePkg / Library / BaseLib / X64 / 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
9095d37b 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
13 Used to serialize load and store operations.\r
14\r
15 All loads and stores that proceed calls to this function are guaranteed to be\r
16 globally visible when this function returns.\r
17\r
18**/\r
19VOID\r
20EFIAPI\r
21MemoryFence (\r
22 VOID\r
23 )\r
24{\r
25 // This is a little bit of overkill and it is more about the compiler that it is\r
9095d37b 26 // actually processor synchronization. This is like the _ReadWriteBarrier\r
d01a90fb 27 // Microsoft specific intrinsic\r
cf683fed 28 __asm__ __volatile__ ("":::"memory");\r
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 "pushfq \n\t"\r
83 "pop %0 "\r
84 : "=r" (Eflags) // %0\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 "movd %%mm0, %0 \n\t"\r
155 : "=r" (Data) // %0\r
2f88bd3a 156 );\r
9095d37b 157\r
cf683fed 158 return Data;\r
159}\r
160\r
cf683fed 161/**\r
162 Reads the current value of 64-bit MMX Register #1 (MM1).\r
163\r
164 Reads and returns the current value of MM1. This function is only available\r
165 on IA-32 and X64.\r
166\r
167 @return The current value of MM1.\r
168\r
169**/\r
170UINT64\r
171EFIAPI\r
172AsmReadMm1 (\r
173 VOID\r
174 )\r
175{\r
176 UINT64 Data;\r
177\r
178 __asm__ __volatile__ (\r
179 "movd %%mm1, %0 \n\t"\r
180 : "=r" (Data) // %0\r
2f88bd3a 181 );\r
9095d37b 182\r
cf683fed 183 return Data;\r
184}\r
185\r
cf683fed 186/**\r
187 Reads the current value of 64-bit MMX Register #2 (MM2).\r
188\r
189 Reads and returns the current value of MM2. This function is only available\r
190 on IA-32 and X64.\r
191\r
192 @return The current value of MM2.\r
193\r
194**/\r
195UINT64\r
196EFIAPI\r
197AsmReadMm2 (\r
198 VOID\r
199 )\r
200{\r
201 UINT64 Data;\r
202\r
203 __asm__ __volatile__ (\r
204 "movd %%mm2, %0 \n\t"\r
205 : "=r" (Data) // %0\r
2f88bd3a 206 );\r
9095d37b 207\r
cf683fed 208 return Data;\r
209}\r
210\r
cf683fed 211/**\r
212 Reads the current value of 64-bit MMX Register #3 (MM3).\r
213\r
214 Reads and returns the current value of MM3. This function is only available\r
215 on IA-32 and X64.\r
216\r
217 @return The current value of MM3.\r
218\r
219**/\r
220UINT64\r
221EFIAPI\r
222AsmReadMm3 (\r
223 VOID\r
224 )\r
225{\r
226 UINT64 Data;\r
227\r
228 __asm__ __volatile__ (\r
229 "movd %%mm3, %0 \n\t"\r
230 : "=r" (Data) // %0\r
2f88bd3a 231 );\r
9095d37b 232\r
cf683fed 233 return Data;\r
234}\r
235\r
cf683fed 236/**\r
237 Reads the current value of 64-bit MMX Register #4 (MM4).\r
238\r
239 Reads and returns the current value of MM4. This function is only available\r
240 on IA-32 and X64.\r
241\r
242 @return The current value of MM4.\r
243\r
244**/\r
245UINT64\r
246EFIAPI\r
247AsmReadMm4 (\r
248 VOID\r
249 )\r
250{\r
251 UINT64 Data;\r
252\r
253 __asm__ __volatile__ (\r
254 "movd %%mm4, %0 \n\t"\r
255 : "=r" (Data) // %0\r
2f88bd3a 256 );\r
9095d37b 257\r
cf683fed 258 return Data;\r
259}\r
260\r
cf683fed 261/**\r
262 Reads the current value of 64-bit MMX Register #5 (MM5).\r
263\r
264 Reads and returns the current value of MM5. This function is only available\r
265 on IA-32 and X64.\r
266\r
267 @return The current value of MM5.\r
268\r
269**/\r
270UINT64\r
271EFIAPI\r
272AsmReadMm5 (\r
273 VOID\r
274 )\r
275{\r
276 UINT64 Data;\r
277\r
278 __asm__ __volatile__ (\r
279 "movd %%mm5, %0 \n\t"\r
280 : "=r" (Data) // %0\r
2f88bd3a 281 );\r
9095d37b 282\r
cf683fed 283 return Data;\r
284}\r
285\r
cf683fed 286/**\r
287 Reads the current value of 64-bit MMX Register #6 (MM6).\r
288\r
289 Reads and returns the current value of MM6. This function is only available\r
290 on IA-32 and X64.\r
291\r
292 @return The current value of MM6.\r
293\r
294**/\r
295UINT64\r
296EFIAPI\r
297AsmReadMm6 (\r
298 VOID\r
299 )\r
300{\r
301 UINT64 Data;\r
302\r
303 __asm__ __volatile__ (\r
304 "movd %%mm6, %0 \n\t"\r
305 : "=r" (Data) // %0\r
2f88bd3a 306 );\r
9095d37b 307\r
cf683fed 308 return Data;\r
309}\r
310\r
cf683fed 311/**\r
312 Reads the current value of 64-bit MMX Register #7 (MM7).\r
313\r
314 Reads and returns the current value of MM7. This function is only available\r
315 on IA-32 and X64.\r
316\r
317 @return The current value of MM7.\r
318\r
319**/\r
320UINT64\r
321EFIAPI\r
322AsmReadMm7 (\r
323 VOID\r
324 )\r
325{\r
326 UINT64 Data;\r
327\r
328 __asm__ __volatile__ (\r
329 "movd %%mm7, %0 \n\t"\r
330 : "=r" (Data) // %0\r
2f88bd3a 331 );\r
9095d37b 332\r
cf683fed 333 return Data;\r
334}\r
335\r
cf683fed 336/**\r
337 Writes the current value of 64-bit MMX Register #0 (MM0).\r
338\r
339 Writes the current value of MM0. This function is only available on IA32 and\r
340 X64.\r
341\r
342 @param Value The 64-bit value to write to MM0.\r
343\r
344**/\r
345VOID\r
346EFIAPI\r
347AsmWriteMm0 (\r
2f88bd3a 348 IN UINT64 Value\r
cf683fed 349 )\r
350{\r
351 __asm__ __volatile__ (\r
352 "movd %0, %%mm0" // %0\r
9095d37b 353 :\r
cf683fed 354 : "m" (Value)\r
2f88bd3a 355 );\r
cf683fed 356}\r
357\r
cf683fed 358/**\r
359 Writes the current value of 64-bit MMX Register #1 (MM1).\r
360\r
361 Writes the current value of MM1. This function is only available on IA32 and\r
362 X64.\r
363\r
364 @param Value The 64-bit value to write to MM1.\r
365\r
366**/\r
367VOID\r
368EFIAPI\r
369AsmWriteMm1 (\r
2f88bd3a 370 IN UINT64 Value\r
cf683fed 371 )\r
372{\r
373 __asm__ __volatile__ (\r
374 "movd %0, %%mm1" // %0\r
9095d37b 375 :\r
cf683fed 376 : "m" (Value)\r
2f88bd3a 377 );\r
cf683fed 378}\r
379\r
cf683fed 380/**\r
381 Writes the current value of 64-bit MMX Register #2 (MM2).\r
382\r
383 Writes the current value of MM2. This function is only available on IA32 and\r
384 X64.\r
385\r
386 @param Value The 64-bit value to write to MM2.\r
387\r
388**/\r
389VOID\r
390EFIAPI\r
391AsmWriteMm2 (\r
2f88bd3a 392 IN UINT64 Value\r
cf683fed 393 )\r
394{\r
395 __asm__ __volatile__ (\r
396 "movd %0, %%mm2" // %0\r
9095d37b 397 :\r
cf683fed 398 : "m" (Value)\r
2f88bd3a 399 );\r
cf683fed 400}\r
401\r
cf683fed 402/**\r
403 Writes the current value of 64-bit MMX Register #3 (MM3).\r
404\r
405 Writes the current value of MM3. This function is only available on IA32 and\r
406 X64.\r
407\r
408 @param Value The 64-bit value to write to MM3.\r
409\r
410**/\r
411VOID\r
412EFIAPI\r
413AsmWriteMm3 (\r
2f88bd3a 414 IN UINT64 Value\r
cf683fed 415 )\r
416{\r
417 __asm__ __volatile__ (\r
418 "movd %0, %%mm3" // %0\r
9095d37b 419 :\r
cf683fed 420 : "m" (Value)\r
2f88bd3a 421 );\r
cf683fed 422}\r
423\r
cf683fed 424/**\r
425 Writes the current value of 64-bit MMX Register #4 (MM4).\r
426\r
427 Writes the current value of MM4. This function is only available on IA32 and\r
428 X64.\r
429\r
430 @param Value The 64-bit value to write to MM4.\r
431\r
432**/\r
433VOID\r
434EFIAPI\r
435AsmWriteMm4 (\r
2f88bd3a 436 IN UINT64 Value\r
cf683fed 437 )\r
438{\r
439 __asm__ __volatile__ (\r
440 "movd %0, %%mm4" // %0\r
9095d37b 441 :\r
cf683fed 442 : "m" (Value)\r
2f88bd3a 443 );\r
cf683fed 444}\r
445\r
cf683fed 446/**\r
447 Writes the current value of 64-bit MMX Register #5 (MM5).\r
448\r
449 Writes the current value of MM5. This function is only available on IA32 and\r
450 X64.\r
451\r
452 @param Value The 64-bit value to write to MM5.\r
453\r
454**/\r
455VOID\r
456EFIAPI\r
457AsmWriteMm5 (\r
2f88bd3a 458 IN UINT64 Value\r
cf683fed 459 )\r
460{\r
461 __asm__ __volatile__ (\r
462 "movd %0, %%mm5" // %0\r
9095d37b 463 :\r
cf683fed 464 : "m" (Value)\r
2f88bd3a 465 );\r
cf683fed 466}\r
467\r
cf683fed 468/**\r
469 Writes the current value of 64-bit MMX Register #6 (MM6).\r
470\r
471 Writes the current value of MM6. This function is only available on IA32 and\r
472 X64.\r
473\r
474 @param Value The 64-bit value to write to MM6.\r
475\r
476**/\r
477VOID\r
478EFIAPI\r
479AsmWriteMm6 (\r
2f88bd3a 480 IN UINT64 Value\r
cf683fed 481 )\r
482{\r
483 __asm__ __volatile__ (\r
484 "movd %0, %%mm6" // %0\r
9095d37b 485 :\r
cf683fed 486 : "m" (Value)\r
2f88bd3a 487 );\r
cf683fed 488}\r
489\r
cf683fed 490/**\r
491 Writes the current value of 64-bit MMX Register #7 (MM7).\r
492\r
493 Writes the current value of MM7. This function is only available on IA32 and\r
494 X64.\r
495\r
496 @param Value The 64-bit value to write to MM7.\r
497\r
498**/\r
499VOID\r
500EFIAPI\r
501AsmWriteMm7 (\r
2f88bd3a 502 IN UINT64 Value\r
cf683fed 503 )\r
504{\r
505 __asm__ __volatile__ (\r
506 "movd %0, %%mm7" // %0\r
9095d37b 507 :\r
cf683fed 508 : "m" (Value)\r
2f88bd3a 509 );\r
cf683fed 510}\r
511\r
cf683fed 512/**\r
513 Reads the current value of Time Stamp Counter (TSC).\r
514\r
515 Reads and returns the current value of TSC. This function is only available\r
516 on IA-32 and X64.\r
517\r
518 @return The current value of TSC\r
519\r
520**/\r
521UINT64\r
522EFIAPI\r
523AsmReadTsc (\r
524 VOID\r
525 )\r
526{\r
527 UINT32 LowData;\r
528 UINT32 HiData;\r
9095d37b 529\r
cf683fed 530 __asm__ __volatile__ (\r
531 "rdtsc"\r
532 : "=a" (LowData),\r
533 "=d" (HiData)\r
2f88bd3a 534 );\r
9095d37b
LG
535\r
536 return (((UINT64)HiData) << 32) | LowData;\r
cf683fed 537}\r