]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/Ia32/GccInlinePriv.c
MdePkg/BaseLib: Break out IA32/X64 GCC inline privileged functions
[mirror_edk2.git] / MdePkg / Library / BaseLib / Ia32 / GccInlinePriv.c
CommitLineData
d3c9e40a
MK
1/** @file\r
2 GCC inline implementation of BaseLib processor specific functions that use\r
3 privlidged instructions.\r
4\r
5 Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>\r
6 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
8\r
9**/\r
10\r
11\r
12#include "BaseLibInternals.h"\r
13\r
14/**\r
15 Enables CPU interrupts.\r
16\r
17 Enables CPU interrupts.\r
18\r
19**/\r
20VOID\r
21EFIAPI\r
22EnableInterrupts (\r
23 VOID\r
24 )\r
25{\r
26 __asm__ __volatile__ ("sti"::: "memory");\r
27}\r
28\r
29\r
30/**\r
31 Disables CPU interrupts.\r
32\r
33 Disables CPU interrupts.\r
34\r
35**/\r
36VOID\r
37EFIAPI\r
38DisableInterrupts (\r
39 VOID\r
40 )\r
41{\r
42 __asm__ __volatile__ ("cli"::: "memory");\r
43}\r
44\r
45/**\r
46 Returns a 64-bit Machine Specific Register(MSR).\r
47\r
48 Reads and returns the 64-bit MSR specified by Index. No parameter checking is\r
49 performed on Index, and some Index values may cause CPU exceptions. The\r
50 caller must either guarantee that Index is valid, or the caller must set up\r
51 exception handlers to catch the exceptions. This function is only available\r
52 on IA-32 and X64.\r
53\r
54 @param Index The 32-bit MSR index to read.\r
55\r
56 @return The value of the MSR identified by Index.\r
57\r
58**/\r
59UINT64\r
60EFIAPI\r
61AsmReadMsr64 (\r
62 IN UINT32 Index\r
63 )\r
64{\r
65 UINT64 Data;\r
66\r
67 __asm__ __volatile__ (\r
68 "rdmsr"\r
69 : "=A" (Data) // %0\r
70 : "c" (Index) // %1\r
71 );\r
72\r
73 return Data;\r
74}\r
75\r
76/**\r
77 Writes a 64-bit value to a Machine Specific Register(MSR), and returns the\r
78 value.\r
79\r
80 Writes the 64-bit value specified by Value to the MSR specified by Index. The\r
81 64-bit value written to the MSR is returned. No parameter checking is\r
82 performed on Index or Value, and some of these may cause CPU exceptions. The\r
83 caller must either guarantee that Index and Value are valid, or the caller\r
84 must establish proper exception handlers. This function is only available on\r
85 IA-32 and X64.\r
86\r
87 @param Index The 32-bit MSR index to write.\r
88 @param Value The 64-bit value to write to the MSR.\r
89\r
90 @return Value\r
91\r
92**/\r
93UINT64\r
94EFIAPI\r
95AsmWriteMsr64 (\r
96 IN UINT32 Index,\r
97 IN UINT64 Value\r
98 )\r
99{\r
100 __asm__ __volatile__ (\r
101 "wrmsr"\r
102 :\r
103 : "c" (Index),\r
104 "A" (Value)\r
105 );\r
106\r
107 return Value;\r
108}\r
109\r
110/**\r
111 Reads the current value of the Control Register 0 (CR0).\r
112\r
113 Reads and returns the current value of CR0. This function is only available\r
114 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
115 X64.\r
116\r
117 @return The value of the Control Register 0 (CR0).\r
118\r
119**/\r
120UINTN\r
121EFIAPI\r
122AsmReadCr0 (\r
123 VOID\r
124 )\r
125{\r
126 UINTN Data;\r
127\r
128 __asm__ __volatile__ (\r
129 "movl %%cr0,%0"\r
130 : "=a" (Data)\r
131 );\r
132\r
133 return Data;\r
134}\r
135\r
136\r
137/**\r
138 Reads the current value of the Control Register 2 (CR2).\r
139\r
140 Reads and returns the current value of CR2. This function is only available\r
141 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
142 X64.\r
143\r
144 @return The value of the Control Register 2 (CR2).\r
145\r
146**/\r
147UINTN\r
148EFIAPI\r
149AsmReadCr2 (\r
150 VOID\r
151 )\r
152{\r
153 UINTN Data;\r
154\r
155 __asm__ __volatile__ (\r
156 "movl %%cr2, %0"\r
157 : "=r" (Data)\r
158 );\r
159\r
160 return Data;\r
161}\r
162\r
163/**\r
164 Reads the current value of the Control Register 3 (CR3).\r
165\r
166 Reads and returns the current value of CR3. This function is only available\r
167 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
168 X64.\r
169\r
170 @return The value of the Control Register 3 (CR3).\r
171\r
172**/\r
173UINTN\r
174EFIAPI\r
175AsmReadCr3 (\r
176 VOID\r
177 )\r
178{\r
179 UINTN Data;\r
180\r
181 __asm__ __volatile__ (\r
182 "movl %%cr3, %0"\r
183 : "=r" (Data)\r
184 );\r
185\r
186 return Data;\r
187}\r
188\r
189\r
190/**\r
191 Reads the current value of the Control Register 4 (CR4).\r
192\r
193 Reads and returns the current value of CR4. This function is only available\r
194 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
195 X64.\r
196\r
197 @return The value of the Control Register 4 (CR4).\r
198\r
199**/\r
200UINTN\r
201EFIAPI\r
202AsmReadCr4 (\r
203 VOID\r
204 )\r
205{\r
206 UINTN Data;\r
207\r
208 __asm__ __volatile__ (\r
209 "movl %%cr4, %0"\r
210 : "=a" (Data)\r
211 );\r
212\r
213 return Data;\r
214}\r
215\r
216\r
217/**\r
218 Writes a value to Control Register 0 (CR0).\r
219\r
220 Writes and returns a new value to CR0. This function is only available on\r
221 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
222\r
223 @param Cr0 The value to write to CR0.\r
224\r
225 @return The value written to CR0.\r
226\r
227**/\r
228UINTN\r
229EFIAPI\r
230AsmWriteCr0 (\r
231 UINTN Cr0\r
232 )\r
233{\r
234 __asm__ __volatile__ (\r
235 "movl %0, %%cr0"\r
236 :\r
237 : "r" (Cr0)\r
238 );\r
239 return Cr0;\r
240}\r
241\r
242\r
243/**\r
244 Writes a value to Control Register 2 (CR2).\r
245\r
246 Writes and returns a new value to CR2. This function is only available on\r
247 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
248\r
249 @param Cr2 The value to write to CR2.\r
250\r
251 @return The value written to CR2.\r
252\r
253**/\r
254UINTN\r
255EFIAPI\r
256AsmWriteCr2 (\r
257 UINTN Cr2\r
258 )\r
259{\r
260 __asm__ __volatile__ (\r
261 "movl %0, %%cr2"\r
262 :\r
263 : "r" (Cr2)\r
264 );\r
265 return Cr2;\r
266}\r
267\r
268\r
269/**\r
270 Writes a value to Control Register 3 (CR3).\r
271\r
272 Writes and returns a new value to CR3. This function is only available on\r
273 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
274\r
275 @param Cr3 The value to write to CR3.\r
276\r
277 @return The value written to CR3.\r
278\r
279**/\r
280UINTN\r
281EFIAPI\r
282AsmWriteCr3 (\r
283 UINTN Cr3\r
284 )\r
285{\r
286 __asm__ __volatile__ (\r
287 "movl %0, %%cr3"\r
288 :\r
289 : "r" (Cr3)\r
290 );\r
291 return Cr3;\r
292}\r
293\r
294\r
295/**\r
296 Writes a value to Control Register 4 (CR4).\r
297\r
298 Writes and returns a new value to CR4. This function is only available on\r
299 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
300\r
301 @param Cr4 The value to write to CR4.\r
302\r
303 @return The value written to CR4.\r
304\r
305**/\r
306UINTN\r
307EFIAPI\r
308AsmWriteCr4 (\r
309 UINTN Cr4\r
310 )\r
311{\r
312 __asm__ __volatile__ (\r
313 "movl %0, %%cr4"\r
314 :\r
315 : "r" (Cr4)\r
316 );\r
317 return Cr4;\r
318}\r
319\r
320\r
321/**\r
322 Reads the current value of Debug Register 0 (DR0).\r
323\r
324 Reads and returns the current value of DR0. This function is only available\r
325 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
326 X64.\r
327\r
328 @return The value of Debug Register 0 (DR0).\r
329\r
330**/\r
331UINTN\r
332EFIAPI\r
333AsmReadDr0 (\r
334 VOID\r
335 )\r
336{\r
337 UINTN Data;\r
338\r
339 __asm__ __volatile__ (\r
340 "movl %%dr0, %0"\r
341 : "=r" (Data)\r
342 );\r
343\r
344 return Data;\r
345}\r
346\r
347\r
348/**\r
349 Reads the current value of Debug Register 1 (DR1).\r
350\r
351 Reads and returns the current value of DR1. This function is only available\r
352 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
353 X64.\r
354\r
355 @return The value of Debug Register 1 (DR1).\r
356\r
357**/\r
358UINTN\r
359EFIAPI\r
360AsmReadDr1 (\r
361 VOID\r
362 )\r
363{\r
364 UINTN Data;\r
365\r
366 __asm__ __volatile__ (\r
367 "movl %%dr1, %0"\r
368 : "=r" (Data)\r
369 );\r
370\r
371 return Data;\r
372}\r
373\r
374\r
375/**\r
376 Reads the current value of Debug Register 2 (DR2).\r
377\r
378 Reads and returns the current value of DR2. This function is only available\r
379 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
380 X64.\r
381\r
382 @return The value of Debug Register 2 (DR2).\r
383\r
384**/\r
385UINTN\r
386EFIAPI\r
387AsmReadDr2 (\r
388 VOID\r
389 )\r
390{\r
391 UINTN Data;\r
392\r
393 __asm__ __volatile__ (\r
394 "movl %%dr2, %0"\r
395 : "=r" (Data)\r
396 );\r
397\r
398 return Data;\r
399}\r
400\r
401\r
402/**\r
403 Reads the current value of Debug Register 3 (DR3).\r
404\r
405 Reads and returns the current value of DR3. This function is only available\r
406 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
407 X64.\r
408\r
409 @return The value of Debug Register 3 (DR3).\r
410\r
411**/\r
412UINTN\r
413EFIAPI\r
414AsmReadDr3 (\r
415 VOID\r
416 )\r
417{\r
418 UINTN Data;\r
419\r
420 __asm__ __volatile__ (\r
421 "movl %%dr3, %0"\r
422 : "=r" (Data)\r
423 );\r
424\r
425 return Data;\r
426}\r
427\r
428\r
429/**\r
430 Reads the current value of Debug Register 4 (DR4).\r
431\r
432 Reads and returns the current value of DR4. This function is only available\r
433 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
434 X64.\r
435\r
436 @return The value of Debug Register 4 (DR4).\r
437\r
438**/\r
439UINTN\r
440EFIAPI\r
441AsmReadDr4 (\r
442 VOID\r
443 )\r
444{\r
445 UINTN Data;\r
446\r
447 __asm__ __volatile__ (\r
448 "movl %%dr4, %0"\r
449 : "=r" (Data)\r
450 );\r
451\r
452 return Data;\r
453}\r
454\r
455\r
456/**\r
457 Reads the current value of Debug Register 5 (DR5).\r
458\r
459 Reads and returns the current value of DR5. This function is only available\r
460 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
461 X64.\r
462\r
463 @return The value of Debug Register 5 (DR5).\r
464\r
465**/\r
466UINTN\r
467EFIAPI\r
468AsmReadDr5 (\r
469 VOID\r
470 )\r
471{\r
472 UINTN Data;\r
473\r
474 __asm__ __volatile__ (\r
475 "movl %%dr5, %0"\r
476 : "=r" (Data)\r
477 );\r
478\r
479 return Data;\r
480}\r
481\r
482\r
483/**\r
484 Reads the current value of Debug Register 6 (DR6).\r
485\r
486 Reads and returns the current value of DR6. This function is only available\r
487 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
488 X64.\r
489\r
490 @return The value of Debug Register 6 (DR6).\r
491\r
492**/\r
493UINTN\r
494EFIAPI\r
495AsmReadDr6 (\r
496 VOID\r
497 )\r
498{\r
499 UINTN Data;\r
500\r
501 __asm__ __volatile__ (\r
502 "movl %%dr6, %0"\r
503 : "=r" (Data)\r
504 );\r
505\r
506 return Data;\r
507}\r
508\r
509\r
510/**\r
511 Reads the current value of Debug Register 7 (DR7).\r
512\r
513 Reads and returns the current value of DR7. This function is only available\r
514 on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
515 X64.\r
516\r
517 @return The value of Debug Register 7 (DR7).\r
518\r
519**/\r
520UINTN\r
521EFIAPI\r
522AsmReadDr7 (\r
523 VOID\r
524 )\r
525{\r
526 UINTN Data;\r
527\r
528 __asm__ __volatile__ (\r
529 "movl %%dr7, %0"\r
530 : "=r" (Data)\r
531 );\r
532\r
533 return Data;\r
534}\r
535\r
536\r
537/**\r
538 Writes a value to Debug Register 0 (DR0).\r
539\r
540 Writes and returns a new value to DR0. This function is only available on\r
541 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
542\r
543 @param Dr0 The value to write to Dr0.\r
544\r
545 @return The value written to Debug Register 0 (DR0).\r
546\r
547**/\r
548UINTN\r
549EFIAPI\r
550AsmWriteDr0 (\r
551 UINTN Dr0\r
552 )\r
553{\r
554 __asm__ __volatile__ (\r
555 "movl %0, %%dr0"\r
556 :\r
557 : "r" (Dr0)\r
558 );\r
559 return Dr0;\r
560}\r
561\r
562\r
563/**\r
564 Writes a value to Debug Register 1 (DR1).\r
565\r
566 Writes and returns a new value to DR1. This function is only available on\r
567 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
568\r
569 @param Dr1 The value to write to Dr1.\r
570\r
571 @return The value written to Debug Register 1 (DR1).\r
572\r
573**/\r
574UINTN\r
575EFIAPI\r
576AsmWriteDr1 (\r
577 UINTN Dr1\r
578 )\r
579{\r
580 __asm__ __volatile__ (\r
581 "movl %0, %%dr1"\r
582 :\r
583 : "r" (Dr1)\r
584 );\r
585 return Dr1;\r
586}\r
587\r
588\r
589/**\r
590 Writes a value to Debug Register 2 (DR2).\r
591\r
592 Writes and returns a new value to DR2. This function is only available on\r
593 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
594\r
595 @param Dr2 The value to write to Dr2.\r
596\r
597 @return The value written to Debug Register 2 (DR2).\r
598\r
599**/\r
600UINTN\r
601EFIAPI\r
602AsmWriteDr2 (\r
603 UINTN Dr2\r
604 )\r
605{\r
606 __asm__ __volatile__ (\r
607 "movl %0, %%dr2"\r
608 :\r
609 : "r" (Dr2)\r
610 );\r
611 return Dr2;\r
612}\r
613\r
614\r
615/**\r
616 Writes a value to Debug Register 3 (DR3).\r
617\r
618 Writes and returns a new value to DR3. This function is only available on\r
619 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
620\r
621 @param Dr3 The value to write to Dr3.\r
622\r
623 @return The value written to Debug Register 3 (DR3).\r
624\r
625**/\r
626UINTN\r
627EFIAPI\r
628AsmWriteDr3 (\r
629 UINTN Dr3\r
630 )\r
631{\r
632 __asm__ __volatile__ (\r
633 "movl %0, %%dr3"\r
634 :\r
635 : "r" (Dr3)\r
636 );\r
637 return Dr3;\r
638}\r
639\r
640\r
641/**\r
642 Writes a value to Debug Register 4 (DR4).\r
643\r
644 Writes and returns a new value to DR4. This function is only available on\r
645 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
646\r
647 @param Dr4 The value to write to Dr4.\r
648\r
649 @return The value written to Debug Register 4 (DR4).\r
650\r
651**/\r
652UINTN\r
653EFIAPI\r
654AsmWriteDr4 (\r
655 UINTN Dr4\r
656 )\r
657{\r
658 __asm__ __volatile__ (\r
659 "movl %0, %%dr4"\r
660 :\r
661 : "r" (Dr4)\r
662 );\r
663 return Dr4;\r
664}\r
665\r
666\r
667/**\r
668 Writes a value to Debug Register 5 (DR5).\r
669\r
670 Writes and returns a new value to DR5. This function is only available on\r
671 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
672\r
673 @param Dr5 The value to write to Dr5.\r
674\r
675 @return The value written to Debug Register 5 (DR5).\r
676\r
677**/\r
678UINTN\r
679EFIAPI\r
680AsmWriteDr5 (\r
681 UINTN Dr5\r
682 )\r
683{\r
684 __asm__ __volatile__ (\r
685 "movl %0, %%dr5"\r
686 :\r
687 : "r" (Dr5)\r
688 );\r
689 return Dr5;\r
690}\r
691\r
692\r
693/**\r
694 Writes a value to Debug Register 6 (DR6).\r
695\r
696 Writes and returns a new value to DR6. This function is only available on\r
697 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
698\r
699 @param Dr6 The value to write to Dr6.\r
700\r
701 @return The value written to Debug Register 6 (DR6).\r
702\r
703**/\r
704UINTN\r
705EFIAPI\r
706AsmWriteDr6 (\r
707 UINTN Dr6\r
708 )\r
709{\r
710 __asm__ __volatile__ (\r
711 "movl %0, %%dr6"\r
712 :\r
713 : "r" (Dr6)\r
714 );\r
715 return Dr6;\r
716}\r
717\r
718\r
719/**\r
720 Writes a value to Debug Register 7 (DR7).\r
721\r
722 Writes and returns a new value to DR7. This function is only available on\r
723 IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.\r
724\r
725 @param Dr7 The value to write to Dr7.\r
726\r
727 @return The value written to Debug Register 7 (DR7).\r
728\r
729**/\r
730UINTN\r
731EFIAPI\r
732AsmWriteDr7 (\r
733 UINTN Dr7\r
734 )\r
735{\r
736 __asm__ __volatile__ (\r
737 "movl %0, %%dr7"\r
738 :\r
739 : "r" (Dr7)\r
740 );\r
741 return Dr7;\r
742}\r
743\r
744\r
745/**\r
746 Reads the current value of Code Segment Register (CS).\r
747\r
748 Reads and returns the current value of CS. This function is only available on\r
749 IA-32 and X64.\r
750\r
751 @return The current value of CS.\r
752\r
753**/\r
754UINT16\r
755EFIAPI\r
756AsmReadCs (\r
757 VOID\r
758 )\r
759{\r
760 UINT16 Data;\r
761\r
762 __asm__ __volatile__ (\r
763 "mov %%cs, %0"\r
764 :"=a" (Data)\r
765 );\r
766\r
767 return Data;\r
768}\r
769\r
770\r
771/**\r
772 Reads the current value of Data Segment Register (DS).\r
773\r
774 Reads and returns the current value of DS. This function is only available on\r
775 IA-32 and X64.\r
776\r
777 @return The current value of DS.\r
778\r
779**/\r
780UINT16\r
781EFIAPI\r
782AsmReadDs (\r
783 VOID\r
784 )\r
785{\r
786 UINT16 Data;\r
787\r
788 __asm__ __volatile__ (\r
789 "mov %%ds, %0"\r
790 :"=a" (Data)\r
791 );\r
792\r
793 return Data;\r
794}\r
795\r
796\r
797/**\r
798 Reads the current value of Extra Segment Register (ES).\r
799\r
800 Reads and returns the current value of ES. This function is only available on\r
801 IA-32 and X64.\r
802\r
803 @return The current value of ES.\r
804\r
805**/\r
806UINT16\r
807EFIAPI\r
808AsmReadEs (\r
809 VOID\r
810 )\r
811{\r
812 UINT16 Data;\r
813\r
814 __asm__ __volatile__ (\r
815 "mov %%es, %0"\r
816 :"=a" (Data)\r
817 );\r
818\r
819 return Data;\r
820}\r
821\r
822\r
823/**\r
824 Reads the current value of FS Data Segment Register (FS).\r
825\r
826 Reads and returns the current value of FS. This function is only available on\r
827 IA-32 and X64.\r
828\r
829 @return The current value of FS.\r
830\r
831**/\r
832UINT16\r
833EFIAPI\r
834AsmReadFs (\r
835 VOID\r
836 )\r
837{\r
838 UINT16 Data;\r
839\r
840 __asm__ __volatile__ (\r
841 "mov %%fs, %0"\r
842 :"=a" (Data)\r
843 );\r
844\r
845 return Data;\r
846}\r
847\r
848\r
849/**\r
850 Reads the current value of GS Data Segment Register (GS).\r
851\r
852 Reads and returns the current value of GS. This function is only available on\r
853 IA-32 and X64.\r
854\r
855 @return The current value of GS.\r
856\r
857**/\r
858UINT16\r
859EFIAPI\r
860AsmReadGs (\r
861 VOID\r
862 )\r
863{\r
864 UINT16 Data;\r
865\r
866 __asm__ __volatile__ (\r
867 "mov %%gs, %0"\r
868 :"=a" (Data)\r
869 );\r
870\r
871 return Data;\r
872}\r
873\r
874\r
875/**\r
876 Reads the current value of Stack Segment Register (SS).\r
877\r
878 Reads and returns the current value of SS. This function is only available on\r
879 IA-32 and X64.\r
880\r
881 @return The current value of SS.\r
882\r
883**/\r
884UINT16\r
885EFIAPI\r
886AsmReadSs (\r
887 VOID\r
888 )\r
889{\r
890 UINT16 Data;\r
891\r
892 __asm__ __volatile__ (\r
893 "mov %%ds, %0"\r
894 :"=a" (Data)\r
895 );\r
896\r
897 return Data;\r
898}\r
899\r
900\r
901/**\r
902 Reads the current value of Task Register (TR).\r
903\r
904 Reads and returns the current value of TR. This function is only available on\r
905 IA-32 and X64.\r
906\r
907 @return The current value of TR.\r
908\r
909**/\r
910UINT16\r
911EFIAPI\r
912AsmReadTr (\r
913 VOID\r
914 )\r
915{\r
916 UINT16 Data;\r
917\r
918 __asm__ __volatile__ (\r
919 "str %0"\r
920 : "=a" (Data)\r
921 );\r
922\r
923 return Data;\r
924}\r
925\r
926\r
927/**\r
928 Reads the current Global Descriptor Table Register(GDTR) descriptor.\r
929\r
930 Reads and returns the current GDTR descriptor and returns it in Gdtr. This\r
931 function is only available on IA-32 and X64.\r
932\r
933 @param Gdtr The pointer to a GDTR descriptor.\r
934\r
935**/\r
936VOID\r
937EFIAPI\r
938InternalX86ReadGdtr (\r
939 OUT IA32_DESCRIPTOR *Gdtr\r
940 )\r
941{\r
942 __asm__ __volatile__ (\r
943 "sgdt %0"\r
944 : "=m" (*Gdtr)\r
945 );\r
946}\r
947\r
948\r
949/**\r
950 Writes the current Global Descriptor Table Register (GDTR) descriptor.\r
951\r
952 Writes and the current GDTR descriptor specified by Gdtr. This function is\r
953 only available on IA-32 and X64.\r
954\r
955 @param Gdtr The pointer to a GDTR descriptor.\r
956\r
957**/\r
958VOID\r
959EFIAPI\r
960InternalX86WriteGdtr (\r
961 IN CONST IA32_DESCRIPTOR *Gdtr\r
962 )\r
963{\r
964 __asm__ __volatile__ (\r
965 "lgdt %0"\r
966 :\r
967 : "m" (*Gdtr)\r
968 );\r
969\r
970}\r
971\r
972\r
973/**\r
974 Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.\r
975\r
976 Reads and returns the current IDTR descriptor and returns it in Idtr. This\r
977 function is only available on IA-32 and X64.\r
978\r
979 @param Idtr The pointer to a IDTR descriptor.\r
980\r
981**/\r
982VOID\r
983EFIAPI\r
984InternalX86ReadIdtr (\r
985 OUT IA32_DESCRIPTOR *Idtr\r
986 )\r
987{\r
988 __asm__ __volatile__ (\r
989 "sidt %0"\r
990 : "=m" (*Idtr)\r
991 );\r
992}\r
993\r
994\r
995/**\r
996 Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.\r
997\r
998 Writes the current IDTR descriptor and returns it in Idtr. This function is\r
999 only available on IA-32 and X64.\r
1000\r
1001 @param Idtr The pointer to a IDTR descriptor.\r
1002\r
1003**/\r
1004VOID\r
1005EFIAPI\r
1006InternalX86WriteIdtr (\r
1007 IN CONST IA32_DESCRIPTOR *Idtr\r
1008 )\r
1009{\r
1010 __asm__ __volatile__ (\r
1011 "lidt %0"\r
1012 :\r
1013 : "m" (*Idtr)\r
1014 );\r
1015}\r
1016\r
1017\r
1018/**\r
1019 Reads the current Local Descriptor Table Register(LDTR) selector.\r
1020\r
1021 Reads and returns the current 16-bit LDTR descriptor value. This function is\r
1022 only available on IA-32 and X64.\r
1023\r
1024 @return The current selector of LDT.\r
1025\r
1026**/\r
1027UINT16\r
1028EFIAPI\r
1029AsmReadLdtr (\r
1030 VOID\r
1031 )\r
1032{\r
1033 UINT16 Data;\r
1034\r
1035 __asm__ __volatile__ (\r
1036 "sldt %0"\r
1037 : "=g" (Data) // %0\r
1038 );\r
1039\r
1040 return Data;\r
1041}\r
1042\r
1043\r
1044/**\r
1045 Writes the current Local Descriptor Table Register (GDTR) selector.\r
1046\r
1047 Writes and the current LDTR descriptor specified by Ldtr. This function is\r
1048 only available on IA-32 and X64.\r
1049\r
1050 @param Ldtr 16-bit LDTR selector value.\r
1051\r
1052**/\r
1053VOID\r
1054EFIAPI\r
1055AsmWriteLdtr (\r
1056 IN UINT16 Ldtr\r
1057 )\r
1058{\r
1059 __asm__ __volatile__ (\r
1060 "lldtw %0"\r
1061 :\r
1062 : "g" (Ldtr) // %0\r
1063 );\r
1064}\r
1065\r
1066/**\r
1067 Reads the current value of a Performance Counter (PMC).\r
1068\r
1069 Reads and returns the current value of performance counter specified by\r
1070 Index. This function is only available on IA-32 and X64.\r
1071\r
1072 @param Index The 32-bit Performance Counter index to read.\r
1073\r
1074 @return The value of the PMC specified by Index.\r
1075\r
1076**/\r
1077UINT64\r
1078EFIAPI\r
1079AsmReadPmc (\r
1080 IN UINT32 Index\r
1081 )\r
1082{\r
1083 UINT64 Data;\r
1084\r
1085 __asm__ __volatile__ (\r
1086 "rdpmc"\r
1087 : "=A" (Data)\r
1088 : "c" (Index)\r
1089 );\r
1090\r
1091 return Data;\r
1092}\r
1093\r
1094/**\r
1095 Executes a WBINVD instruction.\r
1096\r
1097 Executes a WBINVD instruction. This function is only available on IA-32 and\r
1098 X64.\r
1099\r
1100**/\r
1101VOID\r
1102EFIAPI\r
1103AsmWbinvd (\r
1104 VOID\r
1105 )\r
1106{\r
1107 __asm__ __volatile__ ("wbinvd":::"memory");\r
1108}\r
1109\r
1110/**\r
1111 Executes a INVD instruction.\r
1112\r
1113 Executes a INVD instruction. This function is only available on IA-32 and\r
1114 X64.\r
1115\r
1116**/\r
1117VOID\r
1118EFIAPI\r
1119AsmInvd (\r
1120 VOID\r
1121 )\r
1122{\r
1123 __asm__ __volatile__ ("invd":::"memory");\r
1124\r
1125}\r
1126\r
1127\r
1128/**\r
1129 Flushes a cache line from all the instruction and data caches within the\r
1130 coherency domain of the CPU.\r
1131\r
1132 Flushed the cache line specified by LinearAddress, and returns LinearAddress.\r
1133 This function is only available on IA-32 and X64.\r
1134\r
1135 @param LinearAddress The address of the cache line to flush. If the CPU is\r
1136 in a physical addressing mode, then LinearAddress is a\r
1137 physical address. If the CPU is in a virtual\r
1138 addressing mode, then LinearAddress is a virtual\r
1139 address.\r
1140\r
1141 @return LinearAddress\r
1142**/\r
1143VOID *\r
1144EFIAPI\r
1145AsmFlushCacheLine (\r
1146 IN VOID *LinearAddress\r
1147 )\r
1148{\r
1149 UINT32 RegEdx;\r
1150\r
1151 //\r
1152 // If the CPU does not support CLFLUSH instruction,\r
1153 // then promote flush range to flush entire cache.\r
1154 //\r
1155 AsmCpuid (0x01, NULL, NULL, NULL, &RegEdx);\r
1156 if ((RegEdx & BIT19) == 0) {\r
1157 __asm__ __volatile__ ("wbinvd":::"memory");\r
1158 return LinearAddress;\r
1159 }\r
1160\r
1161\r
1162 __asm__ __volatile__ (\r
1163 "clflush (%0)"\r
1164 : "+a" (LinearAddress)\r
1165 :\r
1166 : "memory"\r
1167 );\r
1168\r
1169 return LinearAddress;\r
1170}\r