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