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