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