]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/X64/GccInline.c
MdePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdePkg / Library / BaseLib / X64 / GccInline.c
1 /** @file
2 GCC inline implementation of BaseLib processor specific functions.
3
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10
11 #include "BaseLibInternals.h"
12
13
14
15
16 /**
17 Used to serialize load and store operations.
18
19 All loads and stores that proceed calls to this function are guaranteed to be
20 globally visible when this function returns.
21
22 **/
23 VOID
24 EFIAPI
25 MemoryFence (
26 VOID
27 )
28 {
29 // This is a little bit of overkill and it is more about the compiler that it is
30 // actually processor synchronization. This is like the _ReadWriteBarrier
31 // Microsoft specific intrinsic
32 __asm__ __volatile__ ("":::"memory");
33 }
34
35
36 /**
37 Enables CPU interrupts.
38
39 Enables CPU interrupts.
40
41 **/
42 VOID
43 EFIAPI
44 EnableInterrupts (
45 VOID
46 )
47 {
48 __asm__ __volatile__ ("sti"::: "memory");
49 }
50
51
52 /**
53 Disables CPU interrupts.
54
55 Disables CPU interrupts.
56
57 **/
58 VOID
59 EFIAPI
60 DisableInterrupts (
61 VOID
62 )
63 {
64 __asm__ __volatile__ ("cli"::: "memory");
65 }
66
67
68
69
70 /**
71 Requests CPU to pause for a short period of time.
72
73 Requests CPU to pause for a short period of time. Typically used in MP
74 systems to prevent memory starvation while waiting for a spin lock.
75
76 **/
77 VOID
78 EFIAPI
79 CpuPause (
80 VOID
81 )
82 {
83 __asm__ __volatile__ ("pause");
84 }
85
86
87 /**
88 Generates a breakpoint on the CPU.
89
90 Generates a breakpoint on the CPU. The breakpoint must be implemented such
91 that code can resume normal execution after the breakpoint.
92
93 **/
94 VOID
95 EFIAPI
96 CpuBreakpoint (
97 VOID
98 )
99 {
100 __asm__ __volatile__ ("int $3");
101 }
102
103
104
105 /**
106 Returns a 64-bit Machine Specific Register(MSR).
107
108 Reads and returns the 64-bit MSR specified by Index. No parameter checking is
109 performed on Index, and some Index values may cause CPU exceptions. The
110 caller must either guarantee that Index is valid, or the caller must set up
111 exception handlers to catch the exceptions. This function is only available
112 on IA-32 and X64.
113
114 @param Index The 32-bit MSR index to read.
115
116 @return The value of the MSR identified by Index.
117
118 **/
119 UINT64
120 EFIAPI
121 AsmReadMsr64 (
122 IN UINT32 Index
123 )
124 {
125 UINT32 LowData;
126 UINT32 HighData;
127
128 __asm__ __volatile__ (
129 "rdmsr"
130 : "=a" (LowData), // %0
131 "=d" (HighData) // %1
132 : "c" (Index) // %2
133 );
134
135 return (((UINT64)HighData) << 32) | LowData;
136 }
137
138 /**
139 Writes a 64-bit value to a Machine Specific Register(MSR), and returns the
140 value.
141
142 Writes the 64-bit value specified by Value to the MSR specified by Index. The
143 64-bit value written to the MSR is returned. No parameter checking is
144 performed on Index or Value, and some of these may cause CPU exceptions. The
145 caller must either guarantee that Index and Value are valid, or the caller
146 must establish proper exception handlers. This function is only available on
147 IA-32 and X64.
148
149 @param Index The 32-bit MSR index to write.
150 @param Value The 64-bit value to write to the MSR.
151
152 @return Value
153
154 **/
155 UINT64
156 EFIAPI
157 AsmWriteMsr64 (
158 IN UINT32 Index,
159 IN UINT64 Value
160 )
161 {
162 UINT32 LowData;
163 UINT32 HighData;
164
165 LowData = (UINT32)(Value);
166 HighData = (UINT32)(Value >> 32);
167
168 __asm__ __volatile__ (
169 "wrmsr"
170 :
171 : "c" (Index),
172 "a" (LowData),
173 "d" (HighData)
174 );
175
176 return Value;
177 }
178
179
180
181 /**
182 Reads the current value of the EFLAGS register.
183
184 Reads and returns the current value of the EFLAGS register. This function is
185 only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a
186 64-bit value on X64.
187
188 @return EFLAGS on IA-32 or RFLAGS on X64.
189
190 **/
191 UINTN
192 EFIAPI
193 AsmReadEflags (
194 VOID
195 )
196 {
197 UINTN Eflags;
198
199 __asm__ __volatile__ (
200 "pushfq \n\t"
201 "pop %0 "
202 : "=r" (Eflags) // %0
203 );
204
205 return Eflags;
206 }
207
208
209
210 /**
211 Reads the current value of the Control Register 0 (CR0).
212
213 Reads and returns the current value of CR0. This function is only available
214 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
215 X64.
216
217 @return The value of the Control Register 0 (CR0).
218
219 **/
220 UINTN
221 EFIAPI
222 AsmReadCr0 (
223 VOID
224 )
225 {
226 UINTN Data;
227
228 __asm__ __volatile__ (
229 "mov %%cr0,%0"
230 : "=r" (Data) // %0
231 );
232
233 return Data;
234 }
235
236
237 /**
238 Reads the current value of the Control Register 2 (CR2).
239
240 Reads and returns the current value of CR2. This function is only available
241 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
242 X64.
243
244 @return The value of the Control Register 2 (CR2).
245
246 **/
247 UINTN
248 EFIAPI
249 AsmReadCr2 (
250 VOID
251 )
252 {
253 UINTN Data;
254
255 __asm__ __volatile__ (
256 "mov %%cr2, %0"
257 : "=r" (Data) // %0
258 );
259
260 return Data;
261 }
262
263 /**
264 Reads the current value of the Control Register 3 (CR3).
265
266 Reads and returns the current value of CR3. This function is only available
267 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
268 X64.
269
270 @return The value of the Control Register 3 (CR3).
271
272 **/
273 UINTN
274 EFIAPI
275 AsmReadCr3 (
276 VOID
277 )
278 {
279 UINTN Data;
280
281 __asm__ __volatile__ (
282 "mov %%cr3, %0"
283 : "=r" (Data) // %0
284 );
285
286 return Data;
287 }
288
289
290 /**
291 Reads the current value of the Control Register 4 (CR4).
292
293 Reads and returns the current value of CR4. This function is only available
294 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
295 X64.
296
297 @return The value of the Control Register 4 (CR4).
298
299 **/
300 UINTN
301 EFIAPI
302 AsmReadCr4 (
303 VOID
304 )
305 {
306 UINTN Data;
307
308 __asm__ __volatile__ (
309 "mov %%cr4, %0"
310 : "=r" (Data) // %0
311 );
312
313 return Data;
314 }
315
316
317 /**
318 Writes a value to Control Register 0 (CR0).
319
320 Writes and returns a new value to CR0. 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 Cr0 The value to write to CR0.
324
325 @return The value written to CR0.
326
327 **/
328 UINTN
329 EFIAPI
330 AsmWriteCr0 (
331 UINTN Cr0
332 )
333 {
334 __asm__ __volatile__ (
335 "mov %0, %%cr0"
336 :
337 : "r" (Cr0)
338 );
339 return Cr0;
340 }
341
342
343 /**
344 Writes a value to Control Register 2 (CR2).
345
346 Writes and returns a new value to CR2. This function is only available on
347 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
348
349 @param Cr2 The value to write to CR2.
350
351 @return The value written to CR2.
352
353 **/
354 UINTN
355 EFIAPI
356 AsmWriteCr2 (
357 UINTN Cr2
358 )
359 {
360 __asm__ __volatile__ (
361 "mov %0, %%cr2"
362 :
363 : "r" (Cr2)
364 );
365 return Cr2;
366 }
367
368
369 /**
370 Writes a value to Control Register 3 (CR3).
371
372 Writes and returns a new value to CR3. This function is only available on
373 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
374
375 @param Cr3 The value to write to CR3.
376
377 @return The value written to CR3.
378
379 **/
380 UINTN
381 EFIAPI
382 AsmWriteCr3 (
383 UINTN Cr3
384 )
385 {
386 __asm__ __volatile__ (
387 "mov %0, %%cr3"
388 :
389 : "r" (Cr3)
390 );
391 return Cr3;
392 }
393
394
395 /**
396 Writes a value to Control Register 4 (CR4).
397
398 Writes and returns a new value to CR4. This function is only available on
399 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
400
401 @param Cr4 The value to write to CR4.
402
403 @return The value written to CR4.
404
405 **/
406 UINTN
407 EFIAPI
408 AsmWriteCr4 (
409 UINTN Cr4
410 )
411 {
412 __asm__ __volatile__ (
413 "mov %0, %%cr4"
414 :
415 : "r" (Cr4)
416 );
417 return Cr4;
418 }
419
420
421 /**
422 Reads the current value of Debug Register 0 (DR0).
423
424 Reads and returns the current value of DR0. This function is only available
425 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
426 X64.
427
428 @return The value of Debug Register 0 (DR0).
429
430 **/
431 UINTN
432 EFIAPI
433 AsmReadDr0 (
434 VOID
435 )
436 {
437 UINTN Data;
438
439 __asm__ __volatile__ (
440 "mov %%dr0, %0"
441 : "=r" (Data)
442 );
443
444 return Data;
445 }
446
447
448 /**
449 Reads the current value of Debug Register 1 (DR1).
450
451 Reads and returns the current value of DR1. This function is only available
452 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
453 X64.
454
455 @return The value of Debug Register 1 (DR1).
456
457 **/
458 UINTN
459 EFIAPI
460 AsmReadDr1 (
461 VOID
462 )
463 {
464 UINTN Data;
465
466 __asm__ __volatile__ (
467 "mov %%dr1, %0"
468 : "=r" (Data)
469 );
470
471 return Data;
472 }
473
474
475 /**
476 Reads the current value of Debug Register 2 (DR2).
477
478 Reads and returns the current value of DR2. This function is only available
479 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
480 X64.
481
482 @return The value of Debug Register 2 (DR2).
483
484 **/
485 UINTN
486 EFIAPI
487 AsmReadDr2 (
488 VOID
489 )
490 {
491 UINTN Data;
492
493 __asm__ __volatile__ (
494 "mov %%dr2, %0"
495 : "=r" (Data)
496 );
497
498 return Data;
499 }
500
501
502 /**
503 Reads the current value of Debug Register 3 (DR3).
504
505 Reads and returns the current value of DR3. This function is only available
506 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
507 X64.
508
509 @return The value of Debug Register 3 (DR3).
510
511 **/
512 UINTN
513 EFIAPI
514 AsmReadDr3 (
515 VOID
516 )
517 {
518 UINTN Data;
519
520 __asm__ __volatile__ (
521 "mov %%dr3, %0"
522 : "=r" (Data)
523 );
524
525 return Data;
526 }
527
528
529 /**
530 Reads the current value of Debug Register 4 (DR4).
531
532 Reads and returns the current value of DR4. This function is only available
533 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
534 X64.
535
536 @return The value of Debug Register 4 (DR4).
537
538 **/
539 UINTN
540 EFIAPI
541 AsmReadDr4 (
542 VOID
543 )
544 {
545 UINTN Data;
546
547 __asm__ __volatile__ (
548 "mov %%dr4, %0"
549 : "=r" (Data)
550 );
551
552 return Data;
553 }
554
555
556 /**
557 Reads the current value of Debug Register 5 (DR5).
558
559 Reads and returns the current value of DR5. This function is only available
560 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
561 X64.
562
563 @return The value of Debug Register 5 (DR5).
564
565 **/
566 UINTN
567 EFIAPI
568 AsmReadDr5 (
569 VOID
570 )
571 {
572 UINTN Data;
573
574 __asm__ __volatile__ (
575 "mov %%dr5, %0"
576 : "=r" (Data)
577 );
578
579 return Data;
580 }
581
582
583 /**
584 Reads the current value of Debug Register 6 (DR6).
585
586 Reads and returns the current value of DR6. This function is only available
587 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
588 X64.
589
590 @return The value of Debug Register 6 (DR6).
591
592 **/
593 UINTN
594 EFIAPI
595 AsmReadDr6 (
596 VOID
597 )
598 {
599 UINTN Data;
600
601 __asm__ __volatile__ (
602 "mov %%dr6, %0"
603 : "=r" (Data)
604 );
605
606 return Data;
607 }
608
609
610 /**
611 Reads the current value of Debug Register 7 (DR7).
612
613 Reads and returns the current value of DR7. This function is only available
614 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
615 X64.
616
617 @return The value of Debug Register 7 (DR7).
618
619 **/
620 UINTN
621 EFIAPI
622 AsmReadDr7 (
623 VOID
624 )
625 {
626 UINTN Data;
627
628 __asm__ __volatile__ (
629 "mov %%dr7, %0"
630 : "=r" (Data)
631 );
632
633 return Data;
634 }
635
636
637 /**
638 Writes a value to Debug Register 0 (DR0).
639
640 Writes and returns a new value to DR0. 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 Dr0 The value to write to Dr0.
644
645 @return The value written to Debug Register 0 (DR0).
646
647 **/
648 UINTN
649 EFIAPI
650 AsmWriteDr0 (
651 UINTN Dr0
652 )
653 {
654 __asm__ __volatile__ (
655 "mov %0, %%dr0"
656 :
657 : "r" (Dr0)
658 );
659 return Dr0;
660 }
661
662
663 /**
664 Writes a value to Debug Register 1 (DR1).
665
666 Writes and returns a new value to DR1. 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 Dr1 The value to write to Dr1.
670
671 @return The value written to Debug Register 1 (DR1).
672
673 **/
674 UINTN
675 EFIAPI
676 AsmWriteDr1 (
677 UINTN Dr1
678 )
679 {
680 __asm__ __volatile__ (
681 "mov %0, %%dr1"
682 :
683 : "r" (Dr1)
684 );
685 return Dr1;
686 }
687
688
689 /**
690 Writes a value to Debug Register 2 (DR2).
691
692 Writes and returns a new value to DR2. 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 Dr2 The value to write to Dr2.
696
697 @return The value written to Debug Register 2 (DR2).
698
699 **/
700 UINTN
701 EFIAPI
702 AsmWriteDr2 (
703 UINTN Dr2
704 )
705 {
706 __asm__ __volatile__ (
707 "mov %0, %%dr2"
708 :
709 : "r" (Dr2)
710 );
711 return Dr2;
712 }
713
714
715 /**
716 Writes a value to Debug Register 3 (DR3).
717
718 Writes and returns a new value to DR3. 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 Dr3 The value to write to Dr3.
722
723 @return The value written to Debug Register 3 (DR3).
724
725 **/
726 UINTN
727 EFIAPI
728 AsmWriteDr3 (
729 UINTN Dr3
730 )
731 {
732 __asm__ __volatile__ (
733 "mov %0, %%dr3"
734 :
735 : "r" (Dr3)
736 );
737 return Dr3;
738 }
739
740
741 /**
742 Writes a value to Debug Register 4 (DR4).
743
744 Writes and returns a new value to DR4. 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 Dr4 The value to write to Dr4.
748
749 @return The value written to Debug Register 4 (DR4).
750
751 **/
752 UINTN
753 EFIAPI
754 AsmWriteDr4 (
755 UINTN Dr4
756 )
757 {
758 __asm__ __volatile__ (
759 "mov %0, %%dr4"
760 :
761 : "r" (Dr4)
762 );
763 return Dr4;
764 }
765
766
767 /**
768 Writes a value to Debug Register 5 (DR5).
769
770 Writes and returns a new value to DR5. This function is only available on
771 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
772
773 @param Dr5 The value to write to Dr5.
774
775 @return The value written to Debug Register 5 (DR5).
776
777 **/
778 UINTN
779 EFIAPI
780 AsmWriteDr5 (
781 UINTN Dr5
782 )
783 {
784 __asm__ __volatile__ (
785 "mov %0, %%dr5"
786 :
787 : "r" (Dr5)
788 );
789 return Dr5;
790 }
791
792
793 /**
794 Writes a value to Debug Register 6 (DR6).
795
796 Writes and returns a new value to DR6. This function is only available on
797 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
798
799 @param Dr6 The value to write to Dr6.
800
801 @return The value written to Debug Register 6 (DR6).
802
803 **/
804 UINTN
805 EFIAPI
806 AsmWriteDr6 (
807 UINTN Dr6
808 )
809 {
810 __asm__ __volatile__ (
811 "mov %0, %%dr6"
812 :
813 : "r" (Dr6)
814 );
815 return Dr6;
816 }
817
818
819 /**
820 Writes a value to Debug Register 7 (DR7).
821
822 Writes and returns a new value to DR7. This function is only available on
823 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
824
825 @param Dr7 The value to write to Dr7.
826
827 @return The value written to Debug Register 7 (DR7).
828
829 **/
830 UINTN
831 EFIAPI
832 AsmWriteDr7 (
833 UINTN Dr7
834 )
835 {
836 __asm__ __volatile__ (
837 "mov %0, %%dr7"
838 :
839 : "r" (Dr7)
840 );
841 return Dr7;
842 }
843
844
845 /**
846 Reads the current value of Code Segment Register (CS).
847
848 Reads and returns the current value of CS. This function is only available on
849 IA-32 and X64.
850
851 @return The current value of CS.
852
853 **/
854 UINT16
855 EFIAPI
856 AsmReadCs (
857 VOID
858 )
859 {
860 UINT16 Data;
861
862 __asm__ __volatile__ (
863 "mov %%cs, %0"
864 :"=a" (Data)
865 );
866
867 return Data;
868 }
869
870
871 /**
872 Reads the current value of Data Segment Register (DS).
873
874 Reads and returns the current value of DS. This function is only available on
875 IA-32 and X64.
876
877 @return The current value of DS.
878
879 **/
880 UINT16
881 EFIAPI
882 AsmReadDs (
883 VOID
884 )
885 {
886 UINT16 Data;
887
888 __asm__ __volatile__ (
889 "mov %%ds, %0"
890 :"=a" (Data)
891 );
892
893 return Data;
894 }
895
896
897 /**
898 Reads the current value of Extra Segment Register (ES).
899
900 Reads and returns the current value of ES. This function is only available on
901 IA-32 and X64.
902
903 @return The current value of ES.
904
905 **/
906 UINT16
907 EFIAPI
908 AsmReadEs (
909 VOID
910 )
911 {
912 UINT16 Data;
913
914 __asm__ __volatile__ (
915 "mov %%es, %0"
916 :"=a" (Data)
917 );
918
919 return Data;
920 }
921
922
923 /**
924 Reads the current value of FS Data Segment Register (FS).
925
926 Reads and returns the current value of FS. This function is only available on
927 IA-32 and X64.
928
929 @return The current value of FS.
930
931 **/
932 UINT16
933 EFIAPI
934 AsmReadFs (
935 VOID
936 )
937 {
938 UINT16 Data;
939
940 __asm__ __volatile__ (
941 "mov %%fs, %0"
942 :"=a" (Data)
943 );
944
945 return Data;
946 }
947
948
949 /**
950 Reads the current value of GS Data Segment Register (GS).
951
952 Reads and returns the current value of GS. This function is only available on
953 IA-32 and X64.
954
955 @return The current value of GS.
956
957 **/
958 UINT16
959 EFIAPI
960 AsmReadGs (
961 VOID
962 )
963 {
964 UINT16 Data;
965
966 __asm__ __volatile__ (
967 "mov %%gs, %0"
968 :"=a" (Data)
969 );
970
971 return Data;
972 }
973
974
975 /**
976 Reads the current value of Stack Segment Register (SS).
977
978 Reads and returns the current value of SS. This function is only available on
979 IA-32 and X64.
980
981 @return The current value of SS.
982
983 **/
984 UINT16
985 EFIAPI
986 AsmReadSs (
987 VOID
988 )
989 {
990 UINT16 Data;
991
992 __asm__ __volatile__ (
993 "mov %%ds, %0"
994 :"=a" (Data)
995 );
996
997 return Data;
998 }
999
1000
1001 /**
1002 Reads the current value of Task Register (TR).
1003
1004 Reads and returns the current value of TR. This function is only available on
1005 IA-32 and X64.
1006
1007 @return The current value of TR.
1008
1009 **/
1010 UINT16
1011 EFIAPI
1012 AsmReadTr (
1013 VOID
1014 )
1015 {
1016 UINT16 Data;
1017
1018 __asm__ __volatile__ (
1019 "str %0"
1020 : "=r" (Data)
1021 );
1022
1023 return Data;
1024 }
1025
1026
1027 /**
1028 Reads the current Global Descriptor Table Register(GDTR) descriptor.
1029
1030 Reads and returns the current GDTR descriptor and returns it in Gdtr. This
1031 function is only available on IA-32 and X64.
1032
1033 @param Gdtr The pointer to a GDTR descriptor.
1034
1035 **/
1036 VOID
1037 EFIAPI
1038 InternalX86ReadGdtr (
1039 OUT IA32_DESCRIPTOR *Gdtr
1040 )
1041 {
1042 __asm__ __volatile__ (
1043 "sgdt %0"
1044 : "=m" (*Gdtr)
1045 );
1046 }
1047
1048
1049 /**
1050 Writes the current Global Descriptor Table Register (GDTR) descriptor.
1051
1052 Writes and the current GDTR descriptor specified by Gdtr. This function is
1053 only available on IA-32 and X64.
1054
1055 @param Gdtr The pointer to a GDTR descriptor.
1056
1057 **/
1058 VOID
1059 EFIAPI
1060 InternalX86WriteGdtr (
1061 IN CONST IA32_DESCRIPTOR *Gdtr
1062 )
1063 {
1064 __asm__ __volatile__ (
1065 "lgdt %0"
1066 :
1067 : "m" (*Gdtr)
1068 );
1069
1070 }
1071
1072
1073 /**
1074 Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.
1075
1076 Reads and returns the current IDTR descriptor and returns it in Idtr. This
1077 function is only available on IA-32 and X64.
1078
1079 @param Idtr The pointer to a IDTR descriptor.
1080
1081 **/
1082 VOID
1083 EFIAPI
1084 InternalX86ReadIdtr (
1085 OUT IA32_DESCRIPTOR *Idtr
1086 )
1087 {
1088 __asm__ __volatile__ (
1089 "sidt %0"
1090 : "=m" (*Idtr)
1091 );
1092 }
1093
1094
1095 /**
1096 Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.
1097
1098 Writes the current IDTR descriptor and returns it in Idtr. This function is
1099 only available on IA-32 and X64.
1100
1101 @param Idtr The pointer to a IDTR descriptor.
1102
1103 **/
1104 VOID
1105 EFIAPI
1106 InternalX86WriteIdtr (
1107 IN CONST IA32_DESCRIPTOR *Idtr
1108 )
1109 {
1110 __asm__ __volatile__ (
1111 "lidt %0"
1112 :
1113 : "m" (*Idtr)
1114 );
1115 }
1116
1117
1118 /**
1119 Reads the current Local Descriptor Table Register(LDTR) selector.
1120
1121 Reads and returns the current 16-bit LDTR descriptor value. This function is
1122 only available on IA-32 and X64.
1123
1124 @return The current selector of LDT.
1125
1126 **/
1127 UINT16
1128 EFIAPI
1129 AsmReadLdtr (
1130 VOID
1131 )
1132 {
1133 UINT16 Data;
1134
1135 __asm__ __volatile__ (
1136 "sldt %0"
1137 : "=g" (Data) // %0
1138 );
1139
1140 return Data;
1141 }
1142
1143
1144 /**
1145 Writes the current Local Descriptor Table Register (GDTR) selector.
1146
1147 Writes and the current LDTR descriptor specified by Ldtr. This function is
1148 only available on IA-32 and X64.
1149
1150 @param Ldtr 16-bit LDTR selector value.
1151
1152 **/
1153 VOID
1154 EFIAPI
1155 AsmWriteLdtr (
1156 IN UINT16 Ldtr
1157 )
1158 {
1159 __asm__ __volatile__ (
1160 "lldtw %0"
1161 :
1162 : "g" (Ldtr) // %0
1163 );
1164 }
1165
1166
1167 /**
1168 Save the current floating point/SSE/SSE2 context to a buffer.
1169
1170 Saves the current floating point/SSE/SSE2 state to the buffer specified by
1171 Buffer. Buffer must be aligned on a 16-byte boundary. This function is only
1172 available on IA-32 and X64.
1173
1174 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
1175
1176 **/
1177 VOID
1178 EFIAPI
1179 InternalX86FxSave (
1180 OUT IA32_FX_BUFFER *Buffer
1181 )
1182 {
1183 __asm__ __volatile__ (
1184 "fxsave %0"
1185 :
1186 : "m" (*Buffer) // %0
1187 );
1188 }
1189
1190
1191 /**
1192 Restores the current floating point/SSE/SSE2 context from a buffer.
1193
1194 Restores the current floating point/SSE/SSE2 state from the buffer specified
1195 by Buffer. Buffer must be aligned on a 16-byte boundary. This function is
1196 only available on IA-32 and X64.
1197
1198 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
1199
1200 **/
1201 VOID
1202 EFIAPI
1203 InternalX86FxRestore (
1204 IN CONST IA32_FX_BUFFER *Buffer
1205 )
1206 {
1207 __asm__ __volatile__ (
1208 "fxrstor %0"
1209 :
1210 : "m" (*Buffer) // %0
1211 );
1212 }
1213
1214
1215 /**
1216 Reads the current value of 64-bit MMX Register #0 (MM0).
1217
1218 Reads and returns the current value of MM0. This function is only available
1219 on IA-32 and X64.
1220
1221 @return The current value of MM0.
1222
1223 **/
1224 UINT64
1225 EFIAPI
1226 AsmReadMm0 (
1227 VOID
1228 )
1229 {
1230 UINT64 Data;
1231
1232 __asm__ __volatile__ (
1233 "movd %%mm0, %0 \n\t"
1234 : "=r" (Data) // %0
1235 );
1236
1237 return Data;
1238 }
1239
1240
1241 /**
1242 Reads the current value of 64-bit MMX Register #1 (MM1).
1243
1244 Reads and returns the current value of MM1. This function is only available
1245 on IA-32 and X64.
1246
1247 @return The current value of MM1.
1248
1249 **/
1250 UINT64
1251 EFIAPI
1252 AsmReadMm1 (
1253 VOID
1254 )
1255 {
1256 UINT64 Data;
1257
1258 __asm__ __volatile__ (
1259 "movd %%mm1, %0 \n\t"
1260 : "=r" (Data) // %0
1261 );
1262
1263 return Data;
1264 }
1265
1266
1267 /**
1268 Reads the current value of 64-bit MMX Register #2 (MM2).
1269
1270 Reads and returns the current value of MM2. This function is only available
1271 on IA-32 and X64.
1272
1273 @return The current value of MM2.
1274
1275 **/
1276 UINT64
1277 EFIAPI
1278 AsmReadMm2 (
1279 VOID
1280 )
1281 {
1282 UINT64 Data;
1283
1284 __asm__ __volatile__ (
1285 "movd %%mm2, %0 \n\t"
1286 : "=r" (Data) // %0
1287 );
1288
1289 return Data;
1290 }
1291
1292
1293 /**
1294 Reads the current value of 64-bit MMX Register #3 (MM3).
1295
1296 Reads and returns the current value of MM3. This function is only available
1297 on IA-32 and X64.
1298
1299 @return The current value of MM3.
1300
1301 **/
1302 UINT64
1303 EFIAPI
1304 AsmReadMm3 (
1305 VOID
1306 )
1307 {
1308 UINT64 Data;
1309
1310 __asm__ __volatile__ (
1311 "movd %%mm3, %0 \n\t"
1312 : "=r" (Data) // %0
1313 );
1314
1315 return Data;
1316 }
1317
1318
1319 /**
1320 Reads the current value of 64-bit MMX Register #4 (MM4).
1321
1322 Reads and returns the current value of MM4. This function is only available
1323 on IA-32 and X64.
1324
1325 @return The current value of MM4.
1326
1327 **/
1328 UINT64
1329 EFIAPI
1330 AsmReadMm4 (
1331 VOID
1332 )
1333 {
1334 UINT64 Data;
1335
1336 __asm__ __volatile__ (
1337 "movd %%mm4, %0 \n\t"
1338 : "=r" (Data) // %0
1339 );
1340
1341 return Data;
1342 }
1343
1344
1345 /**
1346 Reads the current value of 64-bit MMX Register #5 (MM5).
1347
1348 Reads and returns the current value of MM5. This function is only available
1349 on IA-32 and X64.
1350
1351 @return The current value of MM5.
1352
1353 **/
1354 UINT64
1355 EFIAPI
1356 AsmReadMm5 (
1357 VOID
1358 )
1359 {
1360 UINT64 Data;
1361
1362 __asm__ __volatile__ (
1363 "movd %%mm5, %0 \n\t"
1364 : "=r" (Data) // %0
1365 );
1366
1367 return Data;
1368 }
1369
1370
1371 /**
1372 Reads the current value of 64-bit MMX Register #6 (MM6).
1373
1374 Reads and returns the current value of MM6. This function is only available
1375 on IA-32 and X64.
1376
1377 @return The current value of MM6.
1378
1379 **/
1380 UINT64
1381 EFIAPI
1382 AsmReadMm6 (
1383 VOID
1384 )
1385 {
1386 UINT64 Data;
1387
1388 __asm__ __volatile__ (
1389 "movd %%mm6, %0 \n\t"
1390 : "=r" (Data) // %0
1391 );
1392
1393 return Data;
1394 }
1395
1396
1397 /**
1398 Reads the current value of 64-bit MMX Register #7 (MM7).
1399
1400 Reads and returns the current value of MM7. This function is only available
1401 on IA-32 and X64.
1402
1403 @return The current value of MM7.
1404
1405 **/
1406 UINT64
1407 EFIAPI
1408 AsmReadMm7 (
1409 VOID
1410 )
1411 {
1412 UINT64 Data;
1413
1414 __asm__ __volatile__ (
1415 "movd %%mm7, %0 \n\t"
1416 : "=r" (Data) // %0
1417 );
1418
1419 return Data;
1420 }
1421
1422
1423 /**
1424 Writes the current value of 64-bit MMX Register #0 (MM0).
1425
1426 Writes the current value of MM0. This function is only available on IA32 and
1427 X64.
1428
1429 @param Value The 64-bit value to write to MM0.
1430
1431 **/
1432 VOID
1433 EFIAPI
1434 AsmWriteMm0 (
1435 IN UINT64 Value
1436 )
1437 {
1438 __asm__ __volatile__ (
1439 "movd %0, %%mm0" // %0
1440 :
1441 : "m" (Value)
1442 );
1443 }
1444
1445
1446 /**
1447 Writes the current value of 64-bit MMX Register #1 (MM1).
1448
1449 Writes the current value of MM1. This function is only available on IA32 and
1450 X64.
1451
1452 @param Value The 64-bit value to write to MM1.
1453
1454 **/
1455 VOID
1456 EFIAPI
1457 AsmWriteMm1 (
1458 IN UINT64 Value
1459 )
1460 {
1461 __asm__ __volatile__ (
1462 "movd %0, %%mm1" // %0
1463 :
1464 : "m" (Value)
1465 );
1466 }
1467
1468
1469 /**
1470 Writes the current value of 64-bit MMX Register #2 (MM2).
1471
1472 Writes the current value of MM2. This function is only available on IA32 and
1473 X64.
1474
1475 @param Value The 64-bit value to write to MM2.
1476
1477 **/
1478 VOID
1479 EFIAPI
1480 AsmWriteMm2 (
1481 IN UINT64 Value
1482 )
1483 {
1484 __asm__ __volatile__ (
1485 "movd %0, %%mm2" // %0
1486 :
1487 : "m" (Value)
1488 );
1489 }
1490
1491
1492 /**
1493 Writes the current value of 64-bit MMX Register #3 (MM3).
1494
1495 Writes the current value of MM3. This function is only available on IA32 and
1496 X64.
1497
1498 @param Value The 64-bit value to write to MM3.
1499
1500 **/
1501 VOID
1502 EFIAPI
1503 AsmWriteMm3 (
1504 IN UINT64 Value
1505 )
1506 {
1507 __asm__ __volatile__ (
1508 "movd %0, %%mm3" // %0
1509 :
1510 : "m" (Value)
1511 );
1512 }
1513
1514
1515 /**
1516 Writes the current value of 64-bit MMX Register #4 (MM4).
1517
1518 Writes the current value of MM4. This function is only available on IA32 and
1519 X64.
1520
1521 @param Value The 64-bit value to write to MM4.
1522
1523 **/
1524 VOID
1525 EFIAPI
1526 AsmWriteMm4 (
1527 IN UINT64 Value
1528 )
1529 {
1530 __asm__ __volatile__ (
1531 "movd %0, %%mm4" // %0
1532 :
1533 : "m" (Value)
1534 );
1535 }
1536
1537
1538 /**
1539 Writes the current value of 64-bit MMX Register #5 (MM5).
1540
1541 Writes the current value of MM5. This function is only available on IA32 and
1542 X64.
1543
1544 @param Value The 64-bit value to write to MM5.
1545
1546 **/
1547 VOID
1548 EFIAPI
1549 AsmWriteMm5 (
1550 IN UINT64 Value
1551 )
1552 {
1553 __asm__ __volatile__ (
1554 "movd %0, %%mm5" // %0
1555 :
1556 : "m" (Value)
1557 );
1558 }
1559
1560
1561 /**
1562 Writes the current value of 64-bit MMX Register #6 (MM6).
1563
1564 Writes the current value of MM6. This function is only available on IA32 and
1565 X64.
1566
1567 @param Value The 64-bit value to write to MM6.
1568
1569 **/
1570 VOID
1571 EFIAPI
1572 AsmWriteMm6 (
1573 IN UINT64 Value
1574 )
1575 {
1576 __asm__ __volatile__ (
1577 "movd %0, %%mm6" // %0
1578 :
1579 : "m" (Value)
1580 );
1581 }
1582
1583
1584 /**
1585 Writes the current value of 64-bit MMX Register #7 (MM7).
1586
1587 Writes the current value of MM7. This function is only available on IA32 and
1588 X64.
1589
1590 @param Value The 64-bit value to write to MM7.
1591
1592 **/
1593 VOID
1594 EFIAPI
1595 AsmWriteMm7 (
1596 IN UINT64 Value
1597 )
1598 {
1599 __asm__ __volatile__ (
1600 "movd %0, %%mm7" // %0
1601 :
1602 : "m" (Value)
1603 );
1604 }
1605
1606
1607 /**
1608 Reads the current value of Time Stamp Counter (TSC).
1609
1610 Reads and returns the current value of TSC. This function is only available
1611 on IA-32 and X64.
1612
1613 @return The current value of TSC
1614
1615 **/
1616 UINT64
1617 EFIAPI
1618 AsmReadTsc (
1619 VOID
1620 )
1621 {
1622 UINT32 LowData;
1623 UINT32 HiData;
1624
1625 __asm__ __volatile__ (
1626 "rdtsc"
1627 : "=a" (LowData),
1628 "=d" (HiData)
1629 );
1630
1631 return (((UINT64)HiData) << 32) | LowData;
1632 }
1633
1634
1635 /**
1636 Reads the current value of a Performance Counter (PMC).
1637
1638 Reads and returns the current value of performance counter specified by
1639 Index. This function is only available on IA-32 and X64.
1640
1641 @param Index The 32-bit Performance Counter index to read.
1642
1643 @return The value of the PMC specified by Index.
1644
1645 **/
1646 UINT64
1647 EFIAPI
1648 AsmReadPmc (
1649 IN UINT32 Index
1650 )
1651 {
1652 UINT32 LowData;
1653 UINT32 HiData;
1654
1655 __asm__ __volatile__ (
1656 "rdpmc"
1657 : "=a" (LowData),
1658 "=d" (HiData)
1659 : "c" (Index)
1660 );
1661
1662 return (((UINT64)HiData) << 32) | LowData;
1663 }
1664
1665
1666 /**
1667 Sets up a monitor buffer that is used by AsmMwait().
1668
1669 Executes a MONITOR instruction with the register state specified by Eax, Ecx
1670 and Edx. Returns Eax. This function is only available on IA-32 and X64.
1671
1672 @param Eax The value to load into EAX or RAX before executing the MONITOR
1673 instruction.
1674 @param Ecx The value to load into ECX or RCX before executing the MONITOR
1675 instruction.
1676 @param Edx The value to load into EDX or RDX before executing the MONITOR
1677 instruction.
1678
1679 @return Eax
1680
1681 **/
1682 UINTN
1683 EFIAPI
1684 AsmMonitor (
1685 IN UINTN Eax,
1686 IN UINTN Ecx,
1687 IN UINTN Edx
1688 )
1689 {
1690 __asm__ __volatile__ (
1691 "monitor"
1692 :
1693 : "a" (Eax),
1694 "c" (Ecx),
1695 "d" (Edx)
1696 );
1697
1698 return Eax;
1699 }
1700
1701
1702 /**
1703 Executes an MWAIT instruction.
1704
1705 Executes an MWAIT instruction with the register state specified by Eax and
1706 Ecx. Returns Eax. This function is only available on IA-32 and X64.
1707
1708 @param Eax The value to load into EAX or RAX before executing the MONITOR
1709 instruction.
1710 @param Ecx The value to load into ECX or RCX before executing the MONITOR
1711 instruction.
1712
1713 @return Eax
1714
1715 **/
1716 UINTN
1717 EFIAPI
1718 AsmMwait (
1719 IN UINTN Eax,
1720 IN UINTN Ecx
1721 )
1722 {
1723 __asm__ __volatile__ (
1724 "mwait"
1725 :
1726 : "a" (Eax),
1727 "c" (Ecx)
1728 );
1729
1730 return Eax;
1731 }
1732
1733
1734 /**
1735 Executes a WBINVD instruction.
1736
1737 Executes a WBINVD instruction. This function is only available on IA-32 and
1738 X64.
1739
1740 **/
1741 VOID
1742 EFIAPI
1743 AsmWbinvd (
1744 VOID
1745 )
1746 {
1747 __asm__ __volatile__ ("wbinvd":::"memory");
1748 }
1749
1750
1751 /**
1752 Executes a INVD instruction.
1753
1754 Executes a INVD instruction. This function is only available on IA-32 and
1755 X64.
1756
1757 **/
1758 VOID
1759 EFIAPI
1760 AsmInvd (
1761 VOID
1762 )
1763 {
1764 __asm__ __volatile__ ("invd":::"memory");
1765
1766 }
1767
1768
1769 /**
1770 Flushes a cache line from all the instruction and data caches within the
1771 coherency domain of the CPU.
1772
1773 Flushed the cache line specified by LinearAddress, and returns LinearAddress.
1774 This function is only available on IA-32 and X64.
1775
1776 @param LinearAddress The address of the cache line to flush. If the CPU is
1777 in a physical addressing mode, then LinearAddress is a
1778 physical address. If the CPU is in a virtual
1779 addressing mode, then LinearAddress is a virtual
1780 address.
1781
1782 @return LinearAddress
1783 **/
1784 VOID *
1785 EFIAPI
1786 AsmFlushCacheLine (
1787 IN VOID *LinearAddress
1788 )
1789 {
1790 __asm__ __volatile__ (
1791 "clflush (%0)"
1792 :
1793 : "r" (LinearAddress)
1794 : "memory"
1795 );
1796
1797 return LinearAddress;
1798 }
1799
1800