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