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