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