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