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