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