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