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