]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - 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
1/** @file\r
2 GCC inline implementation of BaseLib processor specific functions.\r
3\r
4 Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>\r
5 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
7\r
8**/\r
9\r
10#include "BaseLibInternals.h"\r
11\r
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
26 // actually processor synchronization. This is like the _ReadWriteBarrier\r
27 // Microsoft specific intrinsic\r
28 __asm__ __volatile__ ("":::"memory");\r
29}\r
30\r
31/**\r
32 Requests CPU to pause for a short period of time.\r
33\r
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
36\r
37**/\r
38VOID\r
39EFIAPI\r
40CpuPause (\r
41 VOID\r
42 )\r
43{\r
44 __asm__ __volatile__ ("pause");\r
45}\r
46\r
47/**\r
48 Generates a breakpoint on the CPU.\r
49\r
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
52\r
53**/\r
54VOID\r
55EFIAPI\r
56CpuBreakpoint (\r
57 VOID\r
58 )\r
59{\r
60 __asm__ __volatile__ ("int $3");\r
61}\r
62\r
63/**\r
64 Reads the current value of the EFLAGS register.\r
65\r
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
69\r
70 @return EFLAGS on IA-32 or RFLAGS on X64.\r
71\r
72**/\r
73UINTN\r
74EFIAPI\r
75AsmReadEflags (\r
76 VOID\r
77 )\r
78{\r
79 UINTN Eflags;\r
80\r
81 __asm__ __volatile__ (\r
82 "pushfl \n\t"\r
83 "popl %0 "\r
84 : "=r" (Eflags)\r
85 );\r
86\r
87 return Eflags;\r
88}\r
89\r
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
97 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.\r
98\r
99**/\r
100VOID\r
101EFIAPI\r
102InternalX86FxSave (\r
103 OUT IA32_FX_BUFFER *Buffer\r
104 )\r
105{\r
106 __asm__ __volatile__ (\r
107 "fxsave %0"\r
108 :\r
109 : "m" (*Buffer) // %0\r
110 );\r
111}\r
112\r
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
120 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.\r
121\r
122**/\r
123VOID\r
124EFIAPI\r
125InternalX86FxRestore (\r
126 IN CONST IA32_FX_BUFFER *Buffer\r
127 )\r
128{\r
129 __asm__ __volatile__ (\r
130 "fxrstor %0"\r
131 :\r
132 : "m" (*Buffer) // %0\r
133 );\r
134}\r
135\r
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
160 );\r
161\r
162 return Data;\r
163}\r
164\r
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
189 );\r
190\r
191 return Data;\r
192}\r
193\r
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
218 );\r
219\r
220 return Data;\r
221}\r
222\r
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
247 );\r
248\r
249 return Data;\r
250}\r
251\r
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
276 );\r
277\r
278 return Data;\r
279}\r
280\r
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
305 );\r
306\r
307 return Data;\r
308}\r
309\r
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
334 );\r
335\r
336 return Data;\r
337}\r
338\r
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
363 );\r
364\r
365 return Data;\r
366}\r
367\r
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
380 IN UINT64 Value\r
381 )\r
382{\r
383 __asm__ __volatile__ (\r
384 "movq %0, %%mm0" // %0\r
385 :\r
386 : "m" (Value)\r
387 );\r
388}\r
389\r
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
402 IN UINT64 Value\r
403 )\r
404{\r
405 __asm__ __volatile__ (\r
406 "movq %0, %%mm1" // %0\r
407 :\r
408 : "m" (Value)\r
409 );\r
410}\r
411\r
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
424 IN UINT64 Value\r
425 )\r
426{\r
427 __asm__ __volatile__ (\r
428 "movq %0, %%mm2" // %0\r
429 :\r
430 : "m" (Value)\r
431 );\r
432}\r
433\r
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
446 IN UINT64 Value\r
447 )\r
448{\r
449 __asm__ __volatile__ (\r
450 "movq %0, %%mm3" // %0\r
451 :\r
452 : "m" (Value)\r
453 );\r
454}\r
455\r
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
468 IN UINT64 Value\r
469 )\r
470{\r
471 __asm__ __volatile__ (\r
472 "movq %0, %%mm4" // %0\r
473 :\r
474 : "m" (Value)\r
475 );\r
476}\r
477\r
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
490 IN UINT64 Value\r
491 )\r
492{\r
493 __asm__ __volatile__ (\r
494 "movq %0, %%mm5" // %0\r
495 :\r
496 : "m" (Value)\r
497 );\r
498}\r
499\r
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
512 IN UINT64 Value\r
513 )\r
514{\r
515 __asm__ __volatile__ (\r
516 "movq %0, %%mm6" // %0\r
517 :\r
518 : "m" (Value)\r
519 );\r
520}\r
521\r
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
534 IN UINT64 Value\r
535 )\r
536{\r
537 __asm__ __volatile__ (\r
538 "movq %0, %%mm7" // %0\r
539 :\r
540 : "m" (Value)\r
541 );\r
542}\r
543\r
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
560\r
561 __asm__ __volatile__ (\r
562 "rdtsc"\r
563 : "=A" (Data)\r
564 );\r
565\r
566 return Data;\r
567}\r