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