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