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