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