]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/X64/GccInlinePriv.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdePkg / Library / BaseLib / X64 / GccInlinePriv.c
CommitLineData
d3c9e40a
MK
1/** @file\r
2 GCC inline implementation of BaseLib processor specific functions that use\r
3 privlidged instructions.\r
4\r
dc4d4230 5 Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>\r
d3c9e40a
MK
6 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
8\r
9**/\r
10\r
11\r
12#include "BaseLibInternals.h"\r
dc4d4230 13#include <Library/RegisterFilterLib.h>\r
d3c9e40a
MK
14\r
15/**\r
16 Enables CPU interrupts.\r
17\r
18 Enables CPU interrupts.\r
19\r
20**/\r
21VOID\r
22EFIAPI\r
23EnableInterrupts (\r
24 VOID\r
25 )\r
26{\r
27 __asm__ __volatile__ ("sti"::: "memory");\r
28}\r
29\r
30\r
31/**\r
32 Disables CPU interrupts.\r
33\r
34 Disables CPU interrupts.\r
35\r
36**/\r
37VOID\r
38EFIAPI\r
39DisableInterrupts (\r
40 VOID\r
41 )\r
42{\r
43 __asm__ __volatile__ ("cli"::: "memory");\r
44}\r
45\r
46/**\r
47 Returns a 64-bit Machine Specific Register(MSR).\r
48\r
49 Reads and returns the 64-bit MSR specified by Index. No parameter checking is\r
50 performed on Index, and some Index values may cause CPU exceptions. The\r
51 caller must either guarantee that Index is valid, or the caller must set up\r
52 exception handlers to catch the exceptions. This function is only available\r
53 on IA-32 and X64.\r
54\r
55 @param Index The 32-bit MSR index to read.\r
56\r
57 @return The value of the MSR identified by Index.\r
58\r
59**/\r
60UINT64\r
61EFIAPI\r
62AsmReadMsr64 (\r
63 IN UINT32 Index\r
64 )\r
65{\r
66 UINT32 LowData;\r
67 UINT32 HighData;\r
dc4d4230
DB
68 UINT64 Value;\r
69 BOOLEAN Flag;\r
70\r
71 Flag = FilterBeforeMsrRead (Index, &Value);\r
72 if (Flag) {\r
73 __asm__ __volatile__ (\r
74 "rdmsr"\r
75 : "=a" (LowData), // %0\r
76 "=d" (HighData) // %1\r
77 : "c" (Index) // %2\r
78 );\r
79 Value = (((UINT64)HighData) << 32) | LowData;\r
80 }\r
81 FilterAfterMsrRead (Index, &Value);\r
d3c9e40a 82\r
037090cb 83 return Value;\r
d3c9e40a
MK
84}\r
85\r
86/**\r
87 Writes a 64-bit value to a Machine Specific Register(MSR), and returns the\r
88 value.\r
89\r
90 Writes the 64-bit value specified by Value to the MSR specified by Index. The\r
91 64-bit value written to the MSR is returned. No parameter checking is\r
92 performed on Index or Value, and some of these may cause CPU exceptions. The\r
93 caller must either guarantee that Index and Value are valid, or the caller\r
94 must establish proper exception handlers. This function is only available on\r
95 IA-32 and X64.\r
96\r
97 @param Index The 32-bit MSR index to write.\r
98 @param Value The 64-bit value to write to the MSR.\r
99\r
100 @return Value\r
101\r
102**/\r
103UINT64\r
104EFIAPI\r
105AsmWriteMsr64 (\r
106 IN UINT32 Index,\r
107 IN UINT64 Value\r
108 )\r
109{\r
110 UINT32 LowData;\r
111 UINT32 HighData;\r
dc4d4230 112 BOOLEAN Flag;\r
d3c9e40a 113\r
dc4d4230
DB
114 Flag = FilterBeforeMsrWrite (Index, &Value);\r
115 if (Flag) {\r
037090cb
TN
116 LowData = (UINT32)(Value);\r
117 HighData = (UINT32)(Value >> 32);\r
dc4d4230
DB
118 __asm__ __volatile__ (\r
119 "wrmsr"\r
120 :\r
121 : "c" (Index),\r
122 "a" (LowData),\r
123 "d" (HighData)\r
124 );\r
125 }\r
126 FilterAfterMsrWrite (Index, &Value);\r
d3c9e40a
MK
127\r
128 return Value;\r
129}\r
130\r
131/**\r
132 Reads the current value of the Control Register 0 (CR0).\r
133\r
134 Reads and returns the current value of CR0. This function is only available\r
135 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
136 X64.\r
137\r
138 @return The value of the Control Register 0 (CR0).\r
139\r
140**/\r
141UINTN\r
142EFIAPI\r
143AsmReadCr0 (\r
144 VOID\r
145 )\r
146{\r
147 UINTN Data;\r
148\r
149 __asm__ __volatile__ (\r
150 "mov %%cr0,%0"\r
151 : "=r" (Data) // %0\r
152 );\r
153\r
154 return Data;\r
155}\r
156\r
157\r
158/**\r
159 Reads the current value of the Control Register 2 (CR2).\r
160\r
161 Reads and returns the current value of CR2. This function is only available\r
162 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
163 X64.\r
164\r
165 @return The value of the Control Register 2 (CR2).\r
166\r
167**/\r
168UINTN\r
169EFIAPI\r
170AsmReadCr2 (\r
171 VOID\r
172 )\r
173{\r
174 UINTN Data;\r
175\r
176 __asm__ __volatile__ (\r
177 "mov %%cr2, %0"\r
178 : "=r" (Data) // %0\r
179 );\r
180\r
181 return Data;\r
182}\r
183\r
184/**\r
185 Reads the current value of the Control Register 3 (CR3).\r
186\r
187 Reads and returns the current value of CR3. This function is only available\r
188 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
189 X64.\r
190\r
191 @return The value of the Control Register 3 (CR3).\r
192\r
193**/\r
194UINTN\r
195EFIAPI\r
196AsmReadCr3 (\r
197 VOID\r
198 )\r
199{\r
200 UINTN Data;\r
201\r
202 __asm__ __volatile__ (\r
203 "mov %%cr3, %0"\r
204 : "=r" (Data) // %0\r
205 );\r
206\r
207 return Data;\r
208}\r
209\r
210\r
211/**\r
212 Reads the current value of the Control Register 4 (CR4).\r
213\r
214 Reads and returns the current value of CR4. This function is only available\r
215 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
216 X64.\r
217\r
218 @return The value of the Control Register 4 (CR4).\r
219\r
220**/\r
221UINTN\r
222EFIAPI\r
223AsmReadCr4 (\r
224 VOID\r
225 )\r
226{\r
227 UINTN Data;\r
228\r
229 __asm__ __volatile__ (\r
230 "mov %%cr4, %0"\r
231 : "=r" (Data) // %0\r
232 );\r
233\r
234 return Data;\r
235}\r
236\r
237\r
238/**\r
239 Writes a value to Control Register 0 (CR0).\r
240\r
241 Writes and returns a new value to CR0. This function is only available on\r
242 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
243\r
244 @param Cr0 The value to write to CR0.\r
245\r
246 @return The value written to CR0.\r
247\r
248**/\r
249UINTN\r
250EFIAPI\r
251AsmWriteCr0 (\r
252 UINTN Cr0\r
253 )\r
254{\r
255 __asm__ __volatile__ (\r
256 "mov %0, %%cr0"\r
257 :\r
258 : "r" (Cr0)\r
259 );\r
260 return Cr0;\r
261}\r
262\r
263\r
264/**\r
265 Writes a value to Control Register 2 (CR2).\r
266\r
267 Writes and returns a new value to CR2. This function is only available on\r
268 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
269\r
270 @param Cr2 The value to write to CR2.\r
271\r
272 @return The value written to CR2.\r
273\r
274**/\r
275UINTN\r
276EFIAPI\r
277AsmWriteCr2 (\r
278 UINTN Cr2\r
279 )\r
280{\r
281 __asm__ __volatile__ (\r
282 "mov %0, %%cr2"\r
283 :\r
284 : "r" (Cr2)\r
285 );\r
286 return Cr2;\r
287}\r
288\r
289\r
290/**\r
291 Writes a value to Control Register 3 (CR3).\r
292\r
293 Writes and returns a new value to CR3. This function is only available on\r
294 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
295\r
296 @param Cr3 The value to write to CR3.\r
297\r
298 @return The value written to CR3.\r
299\r
300**/\r
301UINTN\r
302EFIAPI\r
303AsmWriteCr3 (\r
304 UINTN Cr3\r
305 )\r
306{\r
307 __asm__ __volatile__ (\r
308 "mov %0, %%cr3"\r
309 :\r
310 : "r" (Cr3)\r
311 );\r
312 return Cr3;\r
313}\r
314\r
315\r
316/**\r
317 Writes a value to Control Register 4 (CR4).\r
318\r
319 Writes and returns a new value to CR4. This function is only available on\r
320 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
321\r
322 @param Cr4 The value to write to CR4.\r
323\r
324 @return The value written to CR4.\r
325\r
326**/\r
327UINTN\r
328EFIAPI\r
329AsmWriteCr4 (\r
330 UINTN Cr4\r
331 )\r
332{\r
333 __asm__ __volatile__ (\r
334 "mov %0, %%cr4"\r
335 :\r
336 : "r" (Cr4)\r
337 );\r
338 return Cr4;\r
339}\r
340\r
341\r
342/**\r
343 Reads the current value of Debug Register 0 (DR0).\r
344\r
345 Reads and returns the current value of DR0. This function is only available\r
346 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
347 X64.\r
348\r
349 @return The value of Debug Register 0 (DR0).\r
350\r
351**/\r
352UINTN\r
353EFIAPI\r
354AsmReadDr0 (\r
355 VOID\r
356 )\r
357{\r
358 UINTN Data;\r
359\r
360 __asm__ __volatile__ (\r
361 "mov %%dr0, %0"\r
362 : "=r" (Data)\r
363 );\r
364\r
365 return Data;\r
366}\r
367\r
368\r
369/**\r
370 Reads the current value of Debug Register 1 (DR1).\r
371\r
372 Reads and returns the current value of DR1. This function is only available\r
373 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
374 X64.\r
375\r
376 @return The value of Debug Register 1 (DR1).\r
377\r
378**/\r
379UINTN\r
380EFIAPI\r
381AsmReadDr1 (\r
382 VOID\r
383 )\r
384{\r
385 UINTN Data;\r
386\r
387 __asm__ __volatile__ (\r
388 "mov %%dr1, %0"\r
389 : "=r" (Data)\r
390 );\r
391\r
392 return Data;\r
393}\r
394\r
395\r
396/**\r
397 Reads the current value of Debug Register 2 (DR2).\r
398\r
399 Reads and returns the current value of DR2. This function is only available\r
400 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
401 X64.\r
402\r
403 @return The value of Debug Register 2 (DR2).\r
404\r
405**/\r
406UINTN\r
407EFIAPI\r
408AsmReadDr2 (\r
409 VOID\r
410 )\r
411{\r
412 UINTN Data;\r
413\r
414 __asm__ __volatile__ (\r
415 "mov %%dr2, %0"\r
416 : "=r" (Data)\r
417 );\r
418\r
419 return Data;\r
420}\r
421\r
422\r
423/**\r
424 Reads the current value of Debug Register 3 (DR3).\r
425\r
426 Reads and returns the current value of DR3. This function is only available\r
427 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
428 X64.\r
429\r
430 @return The value of Debug Register 3 (DR3).\r
431\r
432**/\r
433UINTN\r
434EFIAPI\r
435AsmReadDr3 (\r
436 VOID\r
437 )\r
438{\r
439 UINTN Data;\r
440\r
441 __asm__ __volatile__ (\r
442 "mov %%dr3, %0"\r
443 : "=r" (Data)\r
444 );\r
445\r
446 return Data;\r
447}\r
448\r
449\r
450/**\r
451 Reads the current value of Debug Register 4 (DR4).\r
452\r
453 Reads and returns the current value of DR4. This function is only available\r
454 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
455 X64.\r
456\r
457 @return The value of Debug Register 4 (DR4).\r
458\r
459**/\r
460UINTN\r
461EFIAPI\r
462AsmReadDr4 (\r
463 VOID\r
464 )\r
465{\r
466 UINTN Data;\r
467\r
468 __asm__ __volatile__ (\r
469 "mov %%dr4, %0"\r
470 : "=r" (Data)\r
471 );\r
472\r
473 return Data;\r
474}\r
475\r
476\r
477/**\r
478 Reads the current value of Debug Register 5 (DR5).\r
479\r
480 Reads and returns the current value of DR5. This function is only available\r
481 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
482 X64.\r
483\r
484 @return The value of Debug Register 5 (DR5).\r
485\r
486**/\r
487UINTN\r
488EFIAPI\r
489AsmReadDr5 (\r
490 VOID\r
491 )\r
492{\r
493 UINTN Data;\r
494\r
495 __asm__ __volatile__ (\r
496 "mov %%dr5, %0"\r
497 : "=r" (Data)\r
498 );\r
499\r
500 return Data;\r
501}\r
502\r
503\r
504/**\r
505 Reads the current value of Debug Register 6 (DR6).\r
506\r
507 Reads and returns the current value of DR6. This function is only available\r
508 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
509 X64.\r
510\r
511 @return The value of Debug Register 6 (DR6).\r
512\r
513**/\r
514UINTN\r
515EFIAPI\r
516AsmReadDr6 (\r
517 VOID\r
518 )\r
519{\r
520 UINTN Data;\r
521\r
522 __asm__ __volatile__ (\r
523 "mov %%dr6, %0"\r
524 : "=r" (Data)\r
525 );\r
526\r
527 return Data;\r
528}\r
529\r
530\r
531/**\r
532 Reads the current value of Debug Register 7 (DR7).\r
533\r
534 Reads and returns the current value of DR7. This function is only available\r
535 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
536 X64.\r
537\r
538 @return The value of Debug Register 7 (DR7).\r
539\r
540**/\r
541UINTN\r
542EFIAPI\r
543AsmReadDr7 (\r
544 VOID\r
545 )\r
546{\r
547 UINTN Data;\r
548\r
549 __asm__ __volatile__ (\r
550 "mov %%dr7, %0"\r
551 : "=r" (Data)\r
552 );\r
553\r
554 return Data;\r
555}\r
556\r
557\r
558/**\r
559 Writes a value to Debug Register 0 (DR0).\r
560\r
561 Writes and returns a new value to DR0. This function is only available on\r
562 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
563\r
564 @param Dr0 The value to write to Dr0.\r
565\r
566 @return The value written to Debug Register 0 (DR0).\r
567\r
568**/\r
569UINTN\r
570EFIAPI\r
571AsmWriteDr0 (\r
572 UINTN Dr0\r
573 )\r
574{\r
575 __asm__ __volatile__ (\r
576 "mov %0, %%dr0"\r
577 :\r
578 : "r" (Dr0)\r
579 );\r
580 return Dr0;\r
581}\r
582\r
583\r
584/**\r
585 Writes a value to Debug Register 1 (DR1).\r
586\r
587 Writes and returns a new value to DR1. This function is only available on\r
588 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
589\r
590 @param Dr1 The value to write to Dr1.\r
591\r
592 @return The value written to Debug Register 1 (DR1).\r
593\r
594**/\r
595UINTN\r
596EFIAPI\r
597AsmWriteDr1 (\r
598 UINTN Dr1\r
599 )\r
600{\r
601 __asm__ __volatile__ (\r
602 "mov %0, %%dr1"\r
603 :\r
604 : "r" (Dr1)\r
605 );\r
606 return Dr1;\r
607}\r
608\r
609\r
610/**\r
611 Writes a value to Debug Register 2 (DR2).\r
612\r
613 Writes and returns a new value to DR2. This function is only available on\r
614 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
615\r
616 @param Dr2 The value to write to Dr2.\r
617\r
618 @return The value written to Debug Register 2 (DR2).\r
619\r
620**/\r
621UINTN\r
622EFIAPI\r
623AsmWriteDr2 (\r
624 UINTN Dr2\r
625 )\r
626{\r
627 __asm__ __volatile__ (\r
628 "mov %0, %%dr2"\r
629 :\r
630 : "r" (Dr2)\r
631 );\r
632 return Dr2;\r
633}\r
634\r
635\r
636/**\r
637 Writes a value to Debug Register 3 (DR3).\r
638\r
639 Writes and returns a new value to DR3. This function is only available on\r
640 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
641\r
642 @param Dr3 The value to write to Dr3.\r
643\r
644 @return The value written to Debug Register 3 (DR3).\r
645\r
646**/\r
647UINTN\r
648EFIAPI\r
649AsmWriteDr3 (\r
650 UINTN Dr3\r
651 )\r
652{\r
653 __asm__ __volatile__ (\r
654 "mov %0, %%dr3"\r
655 :\r
656 : "r" (Dr3)\r
657 );\r
658 return Dr3;\r
659}\r
660\r
661\r
662/**\r
663 Writes a value to Debug Register 4 (DR4).\r
664\r
665 Writes and returns a new value to DR4. This function is only available on\r
666 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
667\r
668 @param Dr4 The value to write to Dr4.\r
669\r
670 @return The value written to Debug Register 4 (DR4).\r
671\r
672**/\r
673UINTN\r
674EFIAPI\r
675AsmWriteDr4 (\r
676 UINTN Dr4\r
677 )\r
678{\r
679 __asm__ __volatile__ (\r
680 "mov %0, %%dr4"\r
681 :\r
682 : "r" (Dr4)\r
683 );\r
684 return Dr4;\r
685}\r
686\r
687\r
688/**\r
689 Writes a value to Debug Register 5 (DR5).\r
690\r
691 Writes and returns a new value to DR5. This function is only available on\r
692 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
693\r
694 @param Dr5 The value to write to Dr5.\r
695\r
696 @return The value written to Debug Register 5 (DR5).\r
697\r
698**/\r
699UINTN\r
700EFIAPI\r
701AsmWriteDr5 (\r
702 UINTN Dr5\r
703 )\r
704{\r
705 __asm__ __volatile__ (\r
706 "mov %0, %%dr5"\r
707 :\r
708 : "r" (Dr5)\r
709 );\r
710 return Dr5;\r
711}\r
712\r
713\r
714/**\r
715 Writes a value to Debug Register 6 (DR6).\r
716\r
717 Writes and returns a new value to DR6. This function is only available on\r
718 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
719\r
720 @param Dr6 The value to write to Dr6.\r
721\r
722 @return The value written to Debug Register 6 (DR6).\r
723\r
724**/\r
725UINTN\r
726EFIAPI\r
727AsmWriteDr6 (\r
728 UINTN Dr6\r
729 )\r
730{\r
731 __asm__ __volatile__ (\r
732 "mov %0, %%dr6"\r
733 :\r
734 : "r" (Dr6)\r
735 );\r
736 return Dr6;\r
737}\r
738\r
739\r
740/**\r
741 Writes a value to Debug Register 7 (DR7).\r
742\r
743 Writes and returns a new value to DR7. This function is only available on\r
744 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
745\r
746 @param Dr7 The value to write to Dr7.\r
747\r
748 @return The value written to Debug Register 7 (DR7).\r
749\r
750**/\r
751UINTN\r
752EFIAPI\r
753AsmWriteDr7 (\r
754 UINTN Dr7\r
755 )\r
756{\r
757 __asm__ __volatile__ (\r
758 "mov %0, %%dr7"\r
759 :\r
760 : "r" (Dr7)\r
761 );\r
762 return Dr7;\r
763}\r
764\r
765\r
766/**\r
767 Reads the current value of Code Segment Register (CS).\r
768\r
769 Reads and returns the current value of CS. This function is only available on\r
770 IA-32 and X64.\r
771\r
772 @return The current value of CS.\r
773\r
774**/\r
775UINT16\r
776EFIAPI\r
777AsmReadCs (\r
778 VOID\r
779 )\r
780{\r
781 UINT16 Data;\r
782\r
783 __asm__ __volatile__ (\r
784 "mov %%cs, %0"\r
785 :"=a" (Data)\r
786 );\r
787\r
788 return Data;\r
789}\r
790\r
791\r
792/**\r
793 Reads the current value of Data Segment Register (DS).\r
794\r
795 Reads and returns the current value of DS. This function is only available on\r
796 IA-32 and X64.\r
797\r
798 @return The current value of DS.\r
799\r
800**/\r
801UINT16\r
802EFIAPI\r
803AsmReadDs (\r
804 VOID\r
805 )\r
806{\r
807 UINT16 Data;\r
808\r
809 __asm__ __volatile__ (\r
810 "mov %%ds, %0"\r
811 :"=a" (Data)\r
812 );\r
813\r
814 return Data;\r
815}\r
816\r
817\r
818/**\r
819 Reads the current value of Extra Segment Register (ES).\r
820\r
821 Reads and returns the current value of ES. This function is only available on\r
822 IA-32 and X64.\r
823\r
824 @return The current value of ES.\r
825\r
826**/\r
827UINT16\r
828EFIAPI\r
829AsmReadEs (\r
830 VOID\r
831 )\r
832{\r
833 UINT16 Data;\r
834\r
835 __asm__ __volatile__ (\r
836 "mov %%es, %0"\r
837 :"=a" (Data)\r
838 );\r
839\r
840 return Data;\r
841}\r
842\r
843\r
844/**\r
845 Reads the current value of FS Data Segment Register (FS).\r
846\r
847 Reads and returns the current value of FS. This function is only available on\r
848 IA-32 and X64.\r
849\r
850 @return The current value of FS.\r
851\r
852**/\r
853UINT16\r
854EFIAPI\r
855AsmReadFs (\r
856 VOID\r
857 )\r
858{\r
859 UINT16 Data;\r
860\r
861 __asm__ __volatile__ (\r
862 "mov %%fs, %0"\r
863 :"=a" (Data)\r
864 );\r
865\r
866 return Data;\r
867}\r
868\r
869\r
870/**\r
871 Reads the current value of GS Data Segment Register (GS).\r
872\r
873 Reads and returns the current value of GS. This function is only available on\r
874 IA-32 and X64.\r
875\r
876 @return The current value of GS.\r
877\r
878**/\r
879UINT16\r
880EFIAPI\r
881AsmReadGs (\r
882 VOID\r
883 )\r
884{\r
885 UINT16 Data;\r
886\r
887 __asm__ __volatile__ (\r
888 "mov %%gs, %0"\r
889 :"=a" (Data)\r
890 );\r
891\r
892 return Data;\r
893}\r
894\r
895\r
896/**\r
897 Reads the current value of Stack Segment Register (SS).\r
898\r
899 Reads and returns the current value of SS. This function is only available on\r
900 IA-32 and X64.\r
901\r
902 @return The current value of SS.\r
903\r
904**/\r
905UINT16\r
906EFIAPI\r
907AsmReadSs (\r
908 VOID\r
909 )\r
910{\r
911 UINT16 Data;\r
912\r
913 __asm__ __volatile__ (\r
c410ad4d 914 "mov %%ss, %0"\r
d3c9e40a
MK
915 :"=a" (Data)\r
916 );\r
917\r
918 return Data;\r
919}\r
920\r
921\r
922/**\r
923 Reads the current value of Task Register (TR).\r
924\r
925 Reads and returns the current value of TR. This function is only available on\r
926 IA-32 and X64.\r
927\r
928 @return The current value of TR.\r
929\r
930**/\r
931UINT16\r
932EFIAPI\r
933AsmReadTr (\r
934 VOID\r
935 )\r
936{\r
937 UINT16 Data;\r
938\r
939 __asm__ __volatile__ (\r
940 "str %0"\r
941 : "=r" (Data)\r
942 );\r
943\r
944 return Data;\r
945}\r
946\r
947\r
948/**\r
949 Reads the current Global Descriptor Table Register(GDTR) descriptor.\r
950\r
951 Reads and returns the current GDTR descriptor and returns it in Gdtr. This\r
952 function is only available on IA-32 and X64.\r
953\r
954 @param Gdtr The pointer to a GDTR descriptor.\r
955\r
956**/\r
957VOID\r
958EFIAPI\r
959InternalX86ReadGdtr (\r
960 OUT IA32_DESCRIPTOR *Gdtr\r
961 )\r
962{\r
963 __asm__ __volatile__ (\r
964 "sgdt %0"\r
965 : "=m" (*Gdtr)\r
966 );\r
967}\r
968\r
969\r
970/**\r
971 Writes the current Global Descriptor Table Register (GDTR) descriptor.\r
972\r
973 Writes and the current GDTR descriptor specified by Gdtr. This function is\r
974 only available on IA-32 and X64.\r
975\r
976 @param Gdtr The pointer to a GDTR descriptor.\r
977\r
978**/\r
979VOID\r
980EFIAPI\r
981InternalX86WriteGdtr (\r
982 IN CONST IA32_DESCRIPTOR *Gdtr\r
983 )\r
984{\r
985 __asm__ __volatile__ (\r
986 "lgdt %0"\r
987 :\r
988 : "m" (*Gdtr)\r
989 );\r
990\r
991}\r
992\r
993\r
994/**\r
995 Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.\r
996\r
997 Reads and returns the current IDTR descriptor and returns it in Idtr. This\r
998 function is only available on IA-32 and X64.\r
999\r
1000 @param Idtr The pointer to a IDTR descriptor.\r
1001\r
1002**/\r
1003VOID\r
1004EFIAPI\r
1005InternalX86ReadIdtr (\r
1006 OUT IA32_DESCRIPTOR *Idtr\r
1007 )\r
1008{\r
1009 __asm__ __volatile__ (\r
1010 "sidt %0"\r
1011 : "=m" (*Idtr)\r
1012 );\r
1013}\r
1014\r
1015\r
1016/**\r
1017 Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.\r
1018\r
1019 Writes the current IDTR descriptor and returns it in Idtr. This function is\r
1020 only available on IA-32 and X64.\r
1021\r
1022 @param Idtr The pointer to a IDTR descriptor.\r
1023\r
1024**/\r
1025VOID\r
1026EFIAPI\r
1027InternalX86WriteIdtr (\r
1028 IN CONST IA32_DESCRIPTOR *Idtr\r
1029 )\r
1030{\r
1031 __asm__ __volatile__ (\r
1032 "lidt %0"\r
1033 :\r
1034 : "m" (*Idtr)\r
1035 );\r
1036}\r
1037\r
1038\r
1039/**\r
1040 Reads the current Local Descriptor Table Register(LDTR) selector.\r
1041\r
1042 Reads and returns the current 16-bit LDTR descriptor value. This function is\r
1043 only available on IA-32 and X64.\r
1044\r
1045 @return The current selector of LDT.\r
1046\r
1047**/\r
1048UINT16\r
1049EFIAPI\r
1050AsmReadLdtr (\r
1051 VOID\r
1052 )\r
1053{\r
1054 UINT16 Data;\r
1055\r
1056 __asm__ __volatile__ (\r
1057 "sldt %0"\r
1058 : "=g" (Data) // %0\r
1059 );\r
1060\r
1061 return Data;\r
1062}\r
1063\r
1064\r
1065/**\r
1066 Writes the current Local Descriptor Table Register (GDTR) selector.\r
1067\r
1068 Writes and the current LDTR descriptor specified by Ldtr. This function is\r
1069 only available on IA-32 and X64.\r
1070\r
1071 @param Ldtr 16-bit LDTR selector value.\r
1072\r
1073**/\r
1074VOID\r
1075EFIAPI\r
1076AsmWriteLdtr (\r
1077 IN UINT16 Ldtr\r
1078 )\r
1079{\r
1080 __asm__ __volatile__ (\r
1081 "lldtw %0"\r
1082 :\r
1083 : "g" (Ldtr) // %0\r
1084 );\r
1085}\r
1086\r
1087/**\r
1088 Reads the current value of a Performance Counter (PMC).\r
1089\r
1090 Reads and returns the current value of performance counter specified by\r
1091 Index. This function is only available on IA-32 and X64.\r
1092\r
1093 @param Index The 32-bit Performance Counter index to read.\r
1094\r
1095 @return The value of the PMC specified by Index.\r
1096\r
1097**/\r
1098UINT64\r
1099EFIAPI\r
1100AsmReadPmc (\r
1101 IN UINT32 Index\r
1102 )\r
1103{\r
1104 UINT32 LowData;\r
1105 UINT32 HiData;\r
1106\r
1107 __asm__ __volatile__ (\r
1108 "rdpmc"\r
1109 : "=a" (LowData),\r
1110 "=d" (HiData)\r
1111 : "c" (Index)\r
1112 );\r
1113\r
1114 return (((UINT64)HiData) << 32) | LowData;\r
1115}\r
1116\r
1117/**\r
1118 Sets up a monitor buffer that is used by AsmMwait().\r
1119\r
1120 Executes a MONITOR instruction with the register state specified by Eax, Ecx\r
1121 and Edx. Returns Eax. This function is only available on IA-32 and X64.\r
1122\r
1123 @param Eax The value to load into EAX or RAX before executing the MONITOR\r
1124 instruction.\r
1125 @param Ecx The value to load into ECX or RCX before executing the MONITOR\r
1126 instruction.\r
1127 @param Edx The value to load into EDX or RDX before executing the MONITOR\r
1128 instruction.\r
1129\r
1130 @return Eax\r
1131\r
1132**/\r
1133UINTN\r
1134EFIAPI\r
1135AsmMonitor (\r
1136 IN UINTN Eax,\r
1137 IN UINTN Ecx,\r
1138 IN UINTN Edx\r
1139 )\r
1140{\r
1141 __asm__ __volatile__ (\r
1142 "monitor"\r
1143 :\r
1144 : "a" (Eax),\r
1145 "c" (Ecx),\r
1146 "d" (Edx)\r
1147 );\r
1148\r
1149 return Eax;\r
1150}\r
1151\r
1152/**\r
1153 Executes an MWAIT instruction.\r
1154\r
1155 Executes an MWAIT instruction with the register state specified by Eax and\r
1156 Ecx. Returns Eax. This function is only available on IA-32 and X64.\r
1157\r
1158 @param Eax The value to load into EAX or RAX before executing the MONITOR\r
1159 instruction.\r
1160 @param Ecx The value to load into ECX or RCX before executing the MONITOR\r
1161 instruction.\r
1162\r
1163 @return Eax\r
1164\r
1165**/\r
1166UINTN\r
1167EFIAPI\r
1168AsmMwait (\r
1169 IN UINTN Eax,\r
1170 IN UINTN Ecx\r
1171 )\r
1172{\r
1173 __asm__ __volatile__ (\r
1174 "mwait"\r
1175 :\r
1176 : "a" (Eax),\r
1177 "c" (Ecx)\r
1178 );\r
1179\r
1180 return Eax;\r
1181}\r
1182\r
1183/**\r
1184 Executes a WBINVD instruction.\r
1185\r
1186 Executes a WBINVD instruction. This function is only available on IA-32 and\r
1187 X64.\r
1188\r
1189**/\r
1190VOID\r
1191EFIAPI\r
1192AsmWbinvd (\r
1193 VOID\r
1194 )\r
1195{\r
1196 __asm__ __volatile__ ("wbinvd":::"memory");\r
1197}\r
1198\r
1199/**\r
1200 Executes a INVD instruction.\r
1201\r
1202 Executes a INVD instruction. This function is only available on IA-32 and\r
1203 X64.\r
1204\r
1205**/\r
1206VOID\r
1207EFIAPI\r
1208AsmInvd (\r
1209 VOID\r
1210 )\r
1211{\r
1212 __asm__ __volatile__ ("invd":::"memory");\r
1213\r
1214}\r
1215\r
1216\r
1217/**\r
1218 Flushes a cache line from all the instruction and data caches within the\r
1219 coherency domain of the CPU.\r
1220\r
1221 Flushed the cache line specified by LinearAddress, and returns LinearAddress.\r
1222 This function is only available on IA-32 and X64.\r
1223\r
1224 @param LinearAddress The address of the cache line to flush. If the CPU is\r
1225 in a physical addressing mode, then LinearAddress is a\r
1226 physical address. If the CPU is in a virtual\r
1227 addressing mode, then LinearAddress is a virtual\r
1228 address.\r
1229\r
1230 @return LinearAddress\r
1231**/\r
1232VOID *\r
1233EFIAPI\r
1234AsmFlushCacheLine (\r
1235 IN VOID *LinearAddress\r
1236 )\r
1237{\r
1238 __asm__ __volatile__ (\r
1239 "clflush (%0)"\r
1240 :\r
1241 : "r" (LinearAddress)\r
1242 : "memory"\r
1243 );\r
1244\r
1245 return LinearAddress;\r
1246}\r