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