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
MemoryFence(VOID)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
EnableInterrupts(VOID)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
DisableInterrupts(VOID)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
CpuPause(VOID)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
CpuBreakpoint(VOID)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
AsmReadMsr64(IN UINT32 Index)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
AsmWriteMsr64(IN UINT32 Index,IN UINT64 Value)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
AsmReadEflags(VOID)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
AsmReadCr0(VOID)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
AsmReadCr2(VOID)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
AsmReadCr3(VOID)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
AsmReadCr4(VOID)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
AsmWriteCr0(UINTN Cr0)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
AsmWriteCr2(UINTN Cr2)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
AsmWriteCr3(UINTN Cr3)388 AsmWriteCr3 (
389 UINTN Cr3
390 )
391 {
392 __asm__ __volatile__ (
393 "mov %0, %%cr3"
394 :
395 : "r" (Cr3)
396 );
397 return Cr3;
398 }
399
400
401 /**
402 Writes a value to Control Register 4 (CR4).
403
404 Writes and returns a new value to CR4. This function is only available on
405 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
406
407 @param Cr4 The value to write to CR4.
408
409 @return The value written to CR4.
410
411 **/
412 UINTN
413 EFIAPI
AsmWriteCr4(UINTN Cr4)414 AsmWriteCr4 (
415 UINTN Cr4
416 )
417 {
418 __asm__ __volatile__ (
419 "mov %0, %%cr4"
420 :
421 : "r" (Cr4)
422 );
423 return Cr4;
424 }
425
426
427 /**
428 Reads the current value of Debug Register 0 (DR0).
429
430 Reads and returns the current value of DR0. This function is only available
431 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
432 X64.
433
434 @return The value of Debug Register 0 (DR0).
435
436 **/
437 UINTN
438 EFIAPI
AsmReadDr0(VOID)439 AsmReadDr0 (
440 VOID
441 )
442 {
443 UINTN Data;
444
445 __asm__ __volatile__ (
446 "mov %%dr0, %0"
447 : "=r" (Data)
448 );
449
450 return Data;
451 }
452
453
454 /**
455 Reads the current value of Debug Register 1 (DR1).
456
457 Reads and returns the current value of DR1. This function is only available
458 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
459 X64.
460
461 @return The value of Debug Register 1 (DR1).
462
463 **/
464 UINTN
465 EFIAPI
AsmReadDr1(VOID)466 AsmReadDr1 (
467 VOID
468 )
469 {
470 UINTN Data;
471
472 __asm__ __volatile__ (
473 "mov %%dr1, %0"
474 : "=r" (Data)
475 );
476
477 return Data;
478 }
479
480
481 /**
482 Reads the current value of Debug Register 2 (DR2).
483
484 Reads and returns the current value of DR2. This function is only available
485 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
486 X64.
487
488 @return The value of Debug Register 2 (DR2).
489
490 **/
491 UINTN
492 EFIAPI
AsmReadDr2(VOID)493 AsmReadDr2 (
494 VOID
495 )
496 {
497 UINTN Data;
498
499 __asm__ __volatile__ (
500 "mov %%dr2, %0"
501 : "=r" (Data)
502 );
503
504 return Data;
505 }
506
507
508 /**
509 Reads the current value of Debug Register 3 (DR3).
510
511 Reads and returns the current value of DR3. This function is only available
512 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
513 X64.
514
515 @return The value of Debug Register 3 (DR3).
516
517 **/
518 UINTN
519 EFIAPI
AsmReadDr3(VOID)520 AsmReadDr3 (
521 VOID
522 )
523 {
524 UINTN Data;
525
526 __asm__ __volatile__ (
527 "mov %%dr3, %0"
528 : "=r" (Data)
529 );
530
531 return Data;
532 }
533
534
535 /**
536 Reads the current value of Debug Register 4 (DR4).
537
538 Reads and returns the current value of DR4. This function is only available
539 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
540 X64.
541
542 @return The value of Debug Register 4 (DR4).
543
544 **/
545 UINTN
546 EFIAPI
AsmReadDr4(VOID)547 AsmReadDr4 (
548 VOID
549 )
550 {
551 UINTN Data;
552
553 __asm__ __volatile__ (
554 "mov %%dr4, %0"
555 : "=r" (Data)
556 );
557
558 return Data;
559 }
560
561
562 /**
563 Reads the current value of Debug Register 5 (DR5).
564
565 Reads and returns the current value of DR5. This function is only available
566 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
567 X64.
568
569 @return The value of Debug Register 5 (DR5).
570
571 **/
572 UINTN
573 EFIAPI
AsmReadDr5(VOID)574 AsmReadDr5 (
575 VOID
576 )
577 {
578 UINTN Data;
579
580 __asm__ __volatile__ (
581 "mov %%dr5, %0"
582 : "=r" (Data)
583 );
584
585 return Data;
586 }
587
588
589 /**
590 Reads the current value of Debug Register 6 (DR6).
591
592 Reads and returns the current value of DR6. This function is only available
593 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
594 X64.
595
596 @return The value of Debug Register 6 (DR6).
597
598 **/
599 UINTN
600 EFIAPI
AsmReadDr6(VOID)601 AsmReadDr6 (
602 VOID
603 )
604 {
605 UINTN Data;
606
607 __asm__ __volatile__ (
608 "mov %%dr6, %0"
609 : "=r" (Data)
610 );
611
612 return Data;
613 }
614
615
616 /**
617 Reads the current value of Debug Register 7 (DR7).
618
619 Reads and returns the current value of DR7. This function is only available
620 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
621 X64.
622
623 @return The value of Debug Register 7 (DR7).
624
625 **/
626 UINTN
627 EFIAPI
AsmReadDr7(VOID)628 AsmReadDr7 (
629 VOID
630 )
631 {
632 UINTN Data;
633
634 __asm__ __volatile__ (
635 "mov %%dr7, %0"
636 : "=r" (Data)
637 );
638
639 return Data;
640 }
641
642
643 /**
644 Writes a value to Debug Register 0 (DR0).
645
646 Writes and returns a new value to DR0. This function is only available on
647 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
648
649 @param Dr0 The value to write to Dr0.
650
651 @return The value written to Debug Register 0 (DR0).
652
653 **/
654 UINTN
655 EFIAPI
AsmWriteDr0(UINTN Dr0)656 AsmWriteDr0 (
657 UINTN Dr0
658 )
659 {
660 __asm__ __volatile__ (
661 "mov %0, %%dr0"
662 :
663 : "r" (Dr0)
664 );
665 return Dr0;
666 }
667
668
669 /**
670 Writes a value to Debug Register 1 (DR1).
671
672 Writes and returns a new value to DR1. This function is only available on
673 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
674
675 @param Dr1 The value to write to Dr1.
676
677 @return The value written to Debug Register 1 (DR1).
678
679 **/
680 UINTN
681 EFIAPI
AsmWriteDr1(UINTN Dr1)682 AsmWriteDr1 (
683 UINTN Dr1
684 )
685 {
686 __asm__ __volatile__ (
687 "mov %0, %%dr1"
688 :
689 : "r" (Dr1)
690 );
691 return Dr1;
692 }
693
694
695 /**
696 Writes a value to Debug Register 2 (DR2).
697
698 Writes and returns a new value to DR2. This function is only available on
699 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
700
701 @param Dr2 The value to write to Dr2.
702
703 @return The value written to Debug Register 2 (DR2).
704
705 **/
706 UINTN
707 EFIAPI
AsmWriteDr2(UINTN Dr2)708 AsmWriteDr2 (
709 UINTN Dr2
710 )
711 {
712 __asm__ __volatile__ (
713 "mov %0, %%dr2"
714 :
715 : "r" (Dr2)
716 );
717 return Dr2;
718 }
719
720
721 /**
722 Writes a value to Debug Register 3 (DR3).
723
724 Writes and returns a new value to DR3. This function is only available on
725 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
726
727 @param Dr3 The value to write to Dr3.
728
729 @return The value written to Debug Register 3 (DR3).
730
731 **/
732 UINTN
733 EFIAPI
AsmWriteDr3(UINTN Dr3)734 AsmWriteDr3 (
735 UINTN Dr3
736 )
737 {
738 __asm__ __volatile__ (
739 "mov %0, %%dr3"
740 :
741 : "r" (Dr3)
742 );
743 return Dr3;
744 }
745
746
747 /**
748 Writes a value to Debug Register 4 (DR4).
749
750 Writes and returns a new value to DR4. This function is only available on
751 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
752
753 @param Dr4 The value to write to Dr4.
754
755 @return The value written to Debug Register 4 (DR4).
756
757 **/
758 UINTN
759 EFIAPI
AsmWriteDr4(UINTN Dr4)760 AsmWriteDr4 (
761 UINTN Dr4
762 )
763 {
764 __asm__ __volatile__ (
765 "mov %0, %%dr4"
766 :
767 : "r" (Dr4)
768 );
769 return Dr4;
770 }
771
772
773 /**
774 Writes a value to Debug Register 5 (DR5).
775
776 Writes and returns a new value to DR5. This function is only available on
777 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
778
779 @param Dr5 The value to write to Dr5.
780
781 @return The value written to Debug Register 5 (DR5).
782
783 **/
784 UINTN
785 EFIAPI
AsmWriteDr5(UINTN Dr5)786 AsmWriteDr5 (
787 UINTN Dr5
788 )
789 {
790 __asm__ __volatile__ (
791 "mov %0, %%dr5"
792 :
793 : "r" (Dr5)
794 );
795 return Dr5;
796 }
797
798
799 /**
800 Writes a value to Debug Register 6 (DR6).
801
802 Writes and returns a new value to DR6. This function is only available on
803 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
804
805 @param Dr6 The value to write to Dr6.
806
807 @return The value written to Debug Register 6 (DR6).
808
809 **/
810 UINTN
811 EFIAPI
AsmWriteDr6(UINTN Dr6)812 AsmWriteDr6 (
813 UINTN Dr6
814 )
815 {
816 __asm__ __volatile__ (
817 "mov %0, %%dr6"
818 :
819 : "r" (Dr6)
820 );
821 return Dr6;
822 }
823
824
825 /**
826 Writes a value to Debug Register 7 (DR7).
827
828 Writes and returns a new value to DR7. This function is only available on
829 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
830
831 @param Dr7 The value to write to Dr7.
832
833 @return The value written to Debug Register 7 (DR7).
834
835 **/
836 UINTN
837 EFIAPI
AsmWriteDr7(UINTN Dr7)838 AsmWriteDr7 (
839 UINTN Dr7
840 )
841 {
842 __asm__ __volatile__ (
843 "mov %0, %%dr7"
844 :
845 : "r" (Dr7)
846 );
847 return Dr7;
848 }
849
850
851 /**
852 Reads the current value of Code Segment Register (CS).
853
854 Reads and returns the current value of CS. This function is only available on
855 IA-32 and X64.
856
857 @return The current value of CS.
858
859 **/
860 UINT16
861 EFIAPI
AsmReadCs(VOID)862 AsmReadCs (
863 VOID
864 )
865 {
866 UINT16 Data;
867
868 __asm__ __volatile__ (
869 "mov %%cs, %0"
870 :"=a" (Data)
871 );
872
873 return Data;
874 }
875
876
877 /**
878 Reads the current value of Data Segment Register (DS).
879
880 Reads and returns the current value of DS. This function is only available on
881 IA-32 and X64.
882
883 @return The current value of DS.
884
885 **/
886 UINT16
887 EFIAPI
AsmReadDs(VOID)888 AsmReadDs (
889 VOID
890 )
891 {
892 UINT16 Data;
893
894 __asm__ __volatile__ (
895 "mov %%ds, %0"
896 :"=a" (Data)
897 );
898
899 return Data;
900 }
901
902
903 /**
904 Reads the current value of Extra Segment Register (ES).
905
906 Reads and returns the current value of ES. This function is only available on
907 IA-32 and X64.
908
909 @return The current value of ES.
910
911 **/
912 UINT16
913 EFIAPI
AsmReadEs(VOID)914 AsmReadEs (
915 VOID
916 )
917 {
918 UINT16 Data;
919
920 __asm__ __volatile__ (
921 "mov %%es, %0"
922 :"=a" (Data)
923 );
924
925 return Data;
926 }
927
928
929 /**
930 Reads the current value of FS Data Segment Register (FS).
931
932 Reads and returns the current value of FS. This function is only available on
933 IA-32 and X64.
934
935 @return The current value of FS.
936
937 **/
938 UINT16
939 EFIAPI
AsmReadFs(VOID)940 AsmReadFs (
941 VOID
942 )
943 {
944 UINT16 Data;
945
946 __asm__ __volatile__ (
947 "mov %%fs, %0"
948 :"=a" (Data)
949 );
950
951 return Data;
952 }
953
954
955 /**
956 Reads the current value of GS Data Segment Register (GS).
957
958 Reads and returns the current value of GS. This function is only available on
959 IA-32 and X64.
960
961 @return The current value of GS.
962
963 **/
964 UINT16
965 EFIAPI
AsmReadGs(VOID)966 AsmReadGs (
967 VOID
968 )
969 {
970 UINT16 Data;
971
972 __asm__ __volatile__ (
973 "mov %%gs, %0"
974 :"=a" (Data)
975 );
976
977 return Data;
978 }
979
980
981 /**
982 Reads the current value of Stack Segment Register (SS).
983
984 Reads and returns the current value of SS. This function is only available on
985 IA-32 and X64.
986
987 @return The current value of SS.
988
989 **/
990 UINT16
991 EFIAPI
AsmReadSs(VOID)992 AsmReadSs (
993 VOID
994 )
995 {
996 UINT16 Data;
997
998 __asm__ __volatile__ (
999 "mov %%ds, %0"
1000 :"=a" (Data)
1001 );
1002
1003 return Data;
1004 }
1005
1006
1007 /**
1008 Reads the current value of Task Register (TR).
1009
1010 Reads and returns the current value of TR. This function is only available on
1011 IA-32 and X64.
1012
1013 @return The current value of TR.
1014
1015 **/
1016 UINT16
1017 EFIAPI
AsmReadTr(VOID)1018 AsmReadTr (
1019 VOID
1020 )
1021 {
1022 UINT16 Data;
1023
1024 __asm__ __volatile__ (
1025 "str %0"
1026 : "=r" (Data)
1027 );
1028
1029 return Data;
1030 }
1031
1032
1033 /**
1034 Reads the current Global Descriptor Table Register(GDTR) descriptor.
1035
1036 Reads and returns the current GDTR descriptor and returns it in Gdtr. This
1037 function is only available on IA-32 and X64.
1038
1039 @param Gdtr The pointer to a GDTR descriptor.
1040
1041 **/
1042 VOID
1043 EFIAPI
InternalX86ReadGdtr(OUT IA32_DESCRIPTOR * Gdtr)1044 InternalX86ReadGdtr (
1045 OUT IA32_DESCRIPTOR *Gdtr
1046 )
1047 {
1048 __asm__ __volatile__ (
1049 "sgdt %0"
1050 : "=m" (*Gdtr)
1051 );
1052 }
1053
1054
1055 /**
1056 Writes the current Global Descriptor Table Register (GDTR) descriptor.
1057
1058 Writes and the current GDTR descriptor specified by Gdtr. This function is
1059 only available on IA-32 and X64.
1060
1061 @param Gdtr The pointer to a GDTR descriptor.
1062
1063 **/
1064 VOID
1065 EFIAPI
InternalX86WriteGdtr(IN CONST IA32_DESCRIPTOR * Gdtr)1066 InternalX86WriteGdtr (
1067 IN CONST IA32_DESCRIPTOR *Gdtr
1068 )
1069 {
1070 __asm__ __volatile__ (
1071 "lgdt %0"
1072 :
1073 : "m" (*Gdtr)
1074 );
1075
1076 }
1077
1078
1079 /**
1080 Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.
1081
1082 Reads and returns the current IDTR descriptor and returns it in Idtr. This
1083 function is only available on IA-32 and X64.
1084
1085 @param Idtr The pointer to a IDTR descriptor.
1086
1087 **/
1088 VOID
1089 EFIAPI
InternalX86ReadIdtr(OUT IA32_DESCRIPTOR * Idtr)1090 InternalX86ReadIdtr (
1091 OUT IA32_DESCRIPTOR *Idtr
1092 )
1093 {
1094 __asm__ __volatile__ (
1095 "sidt %0"
1096 : "=m" (*Idtr)
1097 );
1098 }
1099
1100
1101 /**
1102 Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.
1103
1104 Writes the current IDTR descriptor and returns it in Idtr. This function is
1105 only available on IA-32 and X64.
1106
1107 @param Idtr The pointer to a IDTR descriptor.
1108
1109 **/
1110 VOID
1111 EFIAPI
InternalX86WriteIdtr(IN CONST IA32_DESCRIPTOR * Idtr)1112 InternalX86WriteIdtr (
1113 IN CONST IA32_DESCRIPTOR *Idtr
1114 )
1115 {
1116 __asm__ __volatile__ (
1117 "lidt %0"
1118 :
1119 : "m" (*Idtr)
1120 );
1121 }
1122
1123
1124 /**
1125 Reads the current Local Descriptor Table Register(LDTR) selector.
1126
1127 Reads and returns the current 16-bit LDTR descriptor value. This function is
1128 only available on IA-32 and X64.
1129
1130 @return The current selector of LDT.
1131
1132 **/
1133 UINT16
1134 EFIAPI
AsmReadLdtr(VOID)1135 AsmReadLdtr (
1136 VOID
1137 )
1138 {
1139 UINT16 Data;
1140
1141 __asm__ __volatile__ (
1142 "sldt %0"
1143 : "=g" (Data) // %0
1144 );
1145
1146 return Data;
1147 }
1148
1149
1150 /**
1151 Writes the current Local Descriptor Table Register (GDTR) selector.
1152
1153 Writes and the current LDTR descriptor specified by Ldtr. This function is
1154 only available on IA-32 and X64.
1155
1156 @param Ldtr 16-bit LDTR selector value.
1157
1158 **/
1159 VOID
1160 EFIAPI
AsmWriteLdtr(IN UINT16 Ldtr)1161 AsmWriteLdtr (
1162 IN UINT16 Ldtr
1163 )
1164 {
1165 __asm__ __volatile__ (
1166 "lldtw %0"
1167 :
1168 : "g" (Ldtr) // %0
1169 );
1170 }
1171
1172
1173 /**
1174 Save the current floating point/SSE/SSE2 context to a buffer.
1175
1176 Saves the current floating point/SSE/SSE2 state to the buffer specified by
1177 Buffer. Buffer must be aligned on a 16-byte boundary. This function is only
1178 available on IA-32 and X64.
1179
1180 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
1181
1182 **/
1183 VOID
1184 EFIAPI
InternalX86FxSave(OUT IA32_FX_BUFFER * Buffer)1185 InternalX86FxSave (
1186 OUT IA32_FX_BUFFER *Buffer
1187 )
1188 {
1189 __asm__ __volatile__ (
1190 "fxsave %0"
1191 :
1192 : "m" (*Buffer) // %0
1193 );
1194 }
1195
1196
1197 /**
1198 Restores the current floating point/SSE/SSE2 context from a buffer.
1199
1200 Restores the current floating point/SSE/SSE2 state from the buffer specified
1201 by Buffer. Buffer must be aligned on a 16-byte boundary. This function is
1202 only available on IA-32 and X64.
1203
1204 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
1205
1206 **/
1207 VOID
1208 EFIAPI
InternalX86FxRestore(IN CONST IA32_FX_BUFFER * Buffer)1209 InternalX86FxRestore (
1210 IN CONST IA32_FX_BUFFER *Buffer
1211 )
1212 {
1213 __asm__ __volatile__ (
1214 "fxrstor %0"
1215 :
1216 : "m" (*Buffer) // %0
1217 );
1218 }
1219
1220
1221 /**
1222 Reads the current value of 64-bit MMX Register #0 (MM0).
1223
1224 Reads and returns the current value of MM0. This function is only available
1225 on IA-32 and X64.
1226
1227 @return The current value of MM0.
1228
1229 **/
1230 UINT64
1231 EFIAPI
AsmReadMm0(VOID)1232 AsmReadMm0 (
1233 VOID
1234 )
1235 {
1236 UINT64 Data;
1237
1238 __asm__ __volatile__ (
1239 "movd %%mm0, %0 \n\t"
1240 : "=r" (Data) // %0
1241 );
1242
1243 return Data;
1244 }
1245
1246
1247 /**
1248 Reads the current value of 64-bit MMX Register #1 (MM1).
1249
1250 Reads and returns the current value of MM1. This function is only available
1251 on IA-32 and X64.
1252
1253 @return The current value of MM1.
1254
1255 **/
1256 UINT64
1257 EFIAPI
AsmReadMm1(VOID)1258 AsmReadMm1 (
1259 VOID
1260 )
1261 {
1262 UINT64 Data;
1263
1264 __asm__ __volatile__ (
1265 "movd %%mm1, %0 \n\t"
1266 : "=r" (Data) // %0
1267 );
1268
1269 return Data;
1270 }
1271
1272
1273 /**
1274 Reads the current value of 64-bit MMX Register #2 (MM2).
1275
1276 Reads and returns the current value of MM2. This function is only available
1277 on IA-32 and X64.
1278
1279 @return The current value of MM2.
1280
1281 **/
1282 UINT64
1283 EFIAPI
AsmReadMm2(VOID)1284 AsmReadMm2 (
1285 VOID
1286 )
1287 {
1288 UINT64 Data;
1289
1290 __asm__ __volatile__ (
1291 "movd %%mm2, %0 \n\t"
1292 : "=r" (Data) // %0
1293 );
1294
1295 return Data;
1296 }
1297
1298
1299 /**
1300 Reads the current value of 64-bit MMX Register #3 (MM3).
1301
1302 Reads and returns the current value of MM3. This function is only available
1303 on IA-32 and X64.
1304
1305 @return The current value of MM3.
1306
1307 **/
1308 UINT64
1309 EFIAPI
AsmReadMm3(VOID)1310 AsmReadMm3 (
1311 VOID
1312 )
1313 {
1314 UINT64 Data;
1315
1316 __asm__ __volatile__ (
1317 "movd %%mm3, %0 \n\t"
1318 : "=r" (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
AsmReadMm4(VOID)1336 AsmReadMm4 (
1337 VOID
1338 )
1339 {
1340 UINT64 Data;
1341
1342 __asm__ __volatile__ (
1343 "movd %%mm4, %0 \n\t"
1344 : "=r" (Data) // %0
1345 );
1346
1347 return Data;
1348 }
1349
1350
1351 /**
1352 Reads the current value of 64-bit MMX Register #5 (MM5).
1353
1354 Reads and returns the current value of MM5. This function is only available
1355 on IA-32 and X64.
1356
1357 @return The current value of MM5.
1358
1359 **/
1360 UINT64
1361 EFIAPI
AsmReadMm5(VOID)1362 AsmReadMm5 (
1363 VOID
1364 )
1365 {
1366 UINT64 Data;
1367
1368 __asm__ __volatile__ (
1369 "movd %%mm5, %0 \n\t"
1370 : "=r" (Data) // %0
1371 );
1372
1373 return Data;
1374 }
1375
1376
1377 /**
1378 Reads the current value of 64-bit MMX Register #6 (MM6).
1379
1380 Reads and returns the current value of MM6. This function is only available
1381 on IA-32 and X64.
1382
1383 @return The current value of MM6.
1384
1385 **/
1386 UINT64
1387 EFIAPI
AsmReadMm6(VOID)1388 AsmReadMm6 (
1389 VOID
1390 )
1391 {
1392 UINT64 Data;
1393
1394 __asm__ __volatile__ (
1395 "movd %%mm6, %0 \n\t"
1396 : "=r" (Data) // %0
1397 );
1398
1399 return Data;
1400 }
1401
1402
1403 /**
1404 Reads the current value of 64-bit MMX Register #7 (MM7).
1405
1406 Reads and returns the current value of MM7. This function is only available
1407 on IA-32 and X64.
1408
1409 @return The current value of MM7.
1410
1411 **/
1412 UINT64
1413 EFIAPI
AsmReadMm7(VOID)1414 AsmReadMm7 (
1415 VOID
1416 )
1417 {
1418 UINT64 Data;
1419
1420 __asm__ __volatile__ (
1421 "movd %%mm7, %0 \n\t"
1422 : "=r" (Data) // %0
1423 );
1424
1425 return Data;
1426 }
1427
1428
1429 /**
1430 Writes the current value of 64-bit MMX Register #0 (MM0).
1431
1432 Writes the current value of MM0. This function is only available on IA32 and
1433 X64.
1434
1435 @param Value The 64-bit value to write to MM0.
1436
1437 **/
1438 VOID
1439 EFIAPI
AsmWriteMm0(IN UINT64 Value)1440 AsmWriteMm0 (
1441 IN UINT64 Value
1442 )
1443 {
1444 __asm__ __volatile__ (
1445 "movd %0, %%mm0" // %0
1446 :
1447 : "m" (Value)
1448 );
1449 }
1450
1451
1452 /**
1453 Writes the current value of 64-bit MMX Register #1 (MM1).
1454
1455 Writes the current value of MM1. This function is only available on IA32 and
1456 X64.
1457
1458 @param Value The 64-bit value to write to MM1.
1459
1460 **/
1461 VOID
1462 EFIAPI
AsmWriteMm1(IN UINT64 Value)1463 AsmWriteMm1 (
1464 IN UINT64 Value
1465 )
1466 {
1467 __asm__ __volatile__ (
1468 "movd %0, %%mm1" // %0
1469 :
1470 : "m" (Value)
1471 );
1472 }
1473
1474
1475 /**
1476 Writes the current value of 64-bit MMX Register #2 (MM2).
1477
1478 Writes the current value of MM2. This function is only available on IA32 and
1479 X64.
1480
1481 @param Value The 64-bit value to write to MM2.
1482
1483 **/
1484 VOID
1485 EFIAPI
AsmWriteMm2(IN UINT64 Value)1486 AsmWriteMm2 (
1487 IN UINT64 Value
1488 )
1489 {
1490 __asm__ __volatile__ (
1491 "movd %0, %%mm2" // %0
1492 :
1493 : "m" (Value)
1494 );
1495 }
1496
1497
1498 /**
1499 Writes the current value of 64-bit MMX Register #3 (MM3).
1500
1501 Writes the current value of MM3. This function is only available on IA32 and
1502 X64.
1503
1504 @param Value The 64-bit value to write to MM3.
1505
1506 **/
1507 VOID
1508 EFIAPI
AsmWriteMm3(IN UINT64 Value)1509 AsmWriteMm3 (
1510 IN UINT64 Value
1511 )
1512 {
1513 __asm__ __volatile__ (
1514 "movd %0, %%mm3" // %0
1515 :
1516 : "m" (Value)
1517 );
1518 }
1519
1520
1521 /**
1522 Writes the current value of 64-bit MMX Register #4 (MM4).
1523
1524 Writes the current value of MM4. This function is only available on IA32 and
1525 X64.
1526
1527 @param Value The 64-bit value to write to MM4.
1528
1529 **/
1530 VOID
1531 EFIAPI
AsmWriteMm4(IN UINT64 Value)1532 AsmWriteMm4 (
1533 IN UINT64 Value
1534 )
1535 {
1536 __asm__ __volatile__ (
1537 "movd %0, %%mm4" // %0
1538 :
1539 : "m" (Value)
1540 );
1541 }
1542
1543
1544 /**
1545 Writes the current value of 64-bit MMX Register #5 (MM5).
1546
1547 Writes the current value of MM5. This function is only available on IA32 and
1548 X64.
1549
1550 @param Value The 64-bit value to write to MM5.
1551
1552 **/
1553 VOID
1554 EFIAPI
AsmWriteMm5(IN UINT64 Value)1555 AsmWriteMm5 (
1556 IN UINT64 Value
1557 )
1558 {
1559 __asm__ __volatile__ (
1560 "movd %0, %%mm5" // %0
1561 :
1562 : "m" (Value)
1563 );
1564 }
1565
1566
1567 /**
1568 Writes the current value of 64-bit MMX Register #6 (MM6).
1569
1570 Writes the current value of MM6. This function is only available on IA32 and
1571 X64.
1572
1573 @param Value The 64-bit value to write to MM6.
1574
1575 **/
1576 VOID
1577 EFIAPI
AsmWriteMm6(IN UINT64 Value)1578 AsmWriteMm6 (
1579 IN UINT64 Value
1580 )
1581 {
1582 __asm__ __volatile__ (
1583 "movd %0, %%mm6" // %0
1584 :
1585 : "m" (Value)
1586 );
1587 }
1588
1589
1590 /**
1591 Writes the current value of 64-bit MMX Register #7 (MM7).
1592
1593 Writes the current value of MM7. This function is only available on IA32 and
1594 X64.
1595
1596 @param Value The 64-bit value to write to MM7.
1597
1598 **/
1599 VOID
1600 EFIAPI
AsmWriteMm7(IN UINT64 Value)1601 AsmWriteMm7 (
1602 IN UINT64 Value
1603 )
1604 {
1605 __asm__ __volatile__ (
1606 "movd %0, %%mm7" // %0
1607 :
1608 : "m" (Value)
1609 );
1610 }
1611
1612
1613 /**
1614 Reads the current value of Time Stamp Counter (TSC).
1615
1616 Reads and returns the current value of TSC. This function is only available
1617 on IA-32 and X64.
1618
1619 @return The current value of TSC
1620
1621 **/
1622 UINT64
1623 EFIAPI
AsmReadTsc(VOID)1624 AsmReadTsc (
1625 VOID
1626 )
1627 {
1628 UINT32 LowData;
1629 UINT32 HiData;
1630
1631 __asm__ __volatile__ (
1632 "rdtsc"
1633 : "=a" (LowData),
1634 "=d" (HiData)
1635 );
1636
1637 return (((UINT64)HiData) << 32) | LowData;
1638 }
1639
1640
1641 /**
1642 Reads the current value of a Performance Counter (PMC).
1643
1644 Reads and returns the current value of performance counter specified by
1645 Index. This function is only available on IA-32 and X64.
1646
1647 @param Index The 32-bit Performance Counter index to read.
1648
1649 @return The value of the PMC specified by Index.
1650
1651 **/
1652 UINT64
1653 EFIAPI
AsmReadPmc(IN UINT32 Index)1654 AsmReadPmc (
1655 IN UINT32 Index
1656 )
1657 {
1658 UINT32 LowData;
1659 UINT32 HiData;
1660
1661 __asm__ __volatile__ (
1662 "rdpmc"
1663 : "=a" (LowData),
1664 "=d" (HiData)
1665 : "c" (Index)
1666 );
1667
1668 return (((UINT64)HiData) << 32) | LowData;
1669 }
1670
1671
1672 /**
1673 Sets up a monitor buffer that is used by AsmMwait().
1674
1675 Executes a MONITOR instruction with the register state specified by Eax, Ecx
1676 and Edx. Returns Eax. This function is only available on IA-32 and X64.
1677
1678 @param Eax The value to load into EAX or RAX before executing the MONITOR
1679 instruction.
1680 @param Ecx The value to load into ECX or RCX before executing the MONITOR
1681 instruction.
1682 @param Edx The value to load into EDX or RDX before executing the MONITOR
1683 instruction.
1684
1685 @return Eax
1686
1687 **/
1688 UINTN
1689 EFIAPI
AsmMonitor(IN UINTN Eax,IN UINTN Ecx,IN UINTN Edx)1690 AsmMonitor (
1691 IN UINTN Eax,
1692 IN UINTN Ecx,
1693 IN UINTN Edx
1694 )
1695 {
1696 __asm__ __volatile__ (
1697 "monitor"
1698 :
1699 : "a" (Eax),
1700 "c" (Ecx),
1701 "d" (Edx)
1702 );
1703
1704 return Eax;
1705 }
1706
1707
1708 /**
1709 Executes an MWAIT instruction.
1710
1711 Executes an MWAIT instruction with the register state specified by Eax and
1712 Ecx. Returns Eax. This function is only available on IA-32 and X64.
1713
1714 @param Eax The value to load into EAX or RAX before executing the MONITOR
1715 instruction.
1716 @param Ecx The value to load into ECX or RCX before executing the MONITOR
1717 instruction.
1718
1719 @return Eax
1720
1721 **/
1722 UINTN
1723 EFIAPI
AsmMwait(IN UINTN Eax,IN UINTN Ecx)1724 AsmMwait (
1725 IN UINTN Eax,
1726 IN UINTN Ecx
1727 )
1728 {
1729 __asm__ __volatile__ (
1730 "mwait"
1731 :
1732 : "a" (Eax),
1733 "c" (Ecx)
1734 );
1735
1736 return Eax;
1737 }
1738
1739
1740 /**
1741 Executes a WBINVD instruction.
1742
1743 Executes a WBINVD instruction. This function is only available on IA-32 and
1744 X64.
1745
1746 **/
1747 VOID
1748 EFIAPI
AsmWbinvd(VOID)1749 AsmWbinvd (
1750 VOID
1751 )
1752 {
1753 __asm__ __volatile__ ("wbinvd":::"memory");
1754 }
1755
1756
1757 /**
1758 Executes a INVD instruction.
1759
1760 Executes a INVD instruction. This function is only available on IA-32 and
1761 X64.
1762
1763 **/
1764 VOID
1765 EFIAPI
AsmInvd(VOID)1766 AsmInvd (
1767 VOID
1768 )
1769 {
1770 __asm__ __volatile__ ("invd":::"memory");
1771
1772 }
1773
1774
1775 /**
1776 Flushes a cache line from all the instruction and data caches within the
1777 coherency domain of the CPU.
1778
1779 Flushed the cache line specified by LinearAddress, and returns LinearAddress.
1780 This function is only available on IA-32 and X64.
1781
1782 @param LinearAddress The address of the cache line to flush. If the CPU is
1783 in a physical addressing mode, then LinearAddress is a
1784 physical address. If the CPU is in a virtual
1785 addressing mode, then LinearAddress is a virtual
1786 address.
1787
1788 @return LinearAddress
1789 **/
1790 VOID *
1791 EFIAPI
AsmFlushCacheLine(IN VOID * LinearAddress)1792 AsmFlushCacheLine (
1793 IN VOID *LinearAddress
1794 )
1795 {
1796 __asm__ __volatile__ (
1797 "clflush (%0)"
1798 :
1799 : "r" (LinearAddress)
1800 : "memory"
1801 );
1802
1803 return LinearAddress;
1804 }
1805
1806
1807