]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/X64/GccInline.c
MdePkg: Apply uncrustify changes
[mirror_edk2.git] / MdePkg / Library / BaseLib / X64 / GccInline.c
1 /** @file
2 GCC inline implementation of BaseLib processor specific functions.
3
4 Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
5 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "BaseLibInternals.h"
11
12 /**
13 Used to serialize load and store operations.
14
15 All loads and stores that proceed calls to this function are guaranteed to be
16 globally visible when this function returns.
17
18 **/
19 VOID
20 EFIAPI
21 MemoryFence (
22 VOID
23 )
24 {
25 // This is a little bit of overkill and it is more about the compiler that it is
26 // actually processor synchronization. This is like the _ReadWriteBarrier
27 // Microsoft specific intrinsic
28 __asm__ __volatile__ ("":::"memory");
29 }
30
31 /**
32 Requests CPU to pause for a short period of time.
33
34 Requests CPU to pause for a short period of time. Typically used in MP
35 systems to prevent memory starvation while waiting for a spin lock.
36
37 **/
38 VOID
39 EFIAPI
40 CpuPause (
41 VOID
42 )
43 {
44 __asm__ __volatile__ ("pause");
45 }
46
47 /**
48 Generates a breakpoint on the CPU.
49
50 Generates a breakpoint on the CPU. The breakpoint must be implemented such
51 that code can resume normal execution after the breakpoint.
52
53 **/
54 VOID
55 EFIAPI
56 CpuBreakpoint (
57 VOID
58 )
59 {
60 __asm__ __volatile__ ("int $3");
61 }
62
63 /**
64 Reads the current value of the EFLAGS register.
65
66 Reads and returns the current value of the EFLAGS register. This function is
67 only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a
68 64-bit value on X64.
69
70 @return EFLAGS on IA-32 or RFLAGS on X64.
71
72 **/
73 UINTN
74 EFIAPI
75 AsmReadEflags (
76 VOID
77 )
78 {
79 UINTN Eflags;
80
81 __asm__ __volatile__ (
82 "pushfq \n\t"
83 "pop %0 "
84 : "=r" (Eflags) // %0
85 );
86
87 return Eflags;
88 }
89
90 /**
91 Save the current floating point/SSE/SSE2 context to a buffer.
92
93 Saves the current floating point/SSE/SSE2 state to the buffer specified by
94 Buffer. Buffer must be aligned on a 16-byte boundary. This function is only
95 available on IA-32 and X64.
96
97 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
98
99 **/
100 VOID
101 EFIAPI
102 InternalX86FxSave (
103 OUT IA32_FX_BUFFER *Buffer
104 )
105 {
106 __asm__ __volatile__ (
107 "fxsave %0"
108 :
109 : "m" (*Buffer) // %0
110 );
111 }
112
113 /**
114 Restores the current floating point/SSE/SSE2 context from a buffer.
115
116 Restores the current floating point/SSE/SSE2 state from the buffer specified
117 by Buffer. Buffer must be aligned on a 16-byte boundary. This function is
118 only available on IA-32 and X64.
119
120 @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
121
122 **/
123 VOID
124 EFIAPI
125 InternalX86FxRestore (
126 IN CONST IA32_FX_BUFFER *Buffer
127 )
128 {
129 __asm__ __volatile__ (
130 "fxrstor %0"
131 :
132 : "m" (*Buffer) // %0
133 );
134 }
135
136 /**
137 Reads the current value of 64-bit MMX Register #0 (MM0).
138
139 Reads and returns the current value of MM0. This function is only available
140 on IA-32 and X64.
141
142 @return The current value of MM0.
143
144 **/
145 UINT64
146 EFIAPI
147 AsmReadMm0 (
148 VOID
149 )
150 {
151 UINT64 Data;
152
153 __asm__ __volatile__ (
154 "movd %%mm0, %0 \n\t"
155 : "=r" (Data) // %0
156 );
157
158 return Data;
159 }
160
161 /**
162 Reads the current value of 64-bit MMX Register #1 (MM1).
163
164 Reads and returns the current value of MM1. This function is only available
165 on IA-32 and X64.
166
167 @return The current value of MM1.
168
169 **/
170 UINT64
171 EFIAPI
172 AsmReadMm1 (
173 VOID
174 )
175 {
176 UINT64 Data;
177
178 __asm__ __volatile__ (
179 "movd %%mm1, %0 \n\t"
180 : "=r" (Data) // %0
181 );
182
183 return Data;
184 }
185
186 /**
187 Reads the current value of 64-bit MMX Register #2 (MM2).
188
189 Reads and returns the current value of MM2. This function is only available
190 on IA-32 and X64.
191
192 @return The current value of MM2.
193
194 **/
195 UINT64
196 EFIAPI
197 AsmReadMm2 (
198 VOID
199 )
200 {
201 UINT64 Data;
202
203 __asm__ __volatile__ (
204 "movd %%mm2, %0 \n\t"
205 : "=r" (Data) // %0
206 );
207
208 return Data;
209 }
210
211 /**
212 Reads the current value of 64-bit MMX Register #3 (MM3).
213
214 Reads and returns the current value of MM3. This function is only available
215 on IA-32 and X64.
216
217 @return The current value of MM3.
218
219 **/
220 UINT64
221 EFIAPI
222 AsmReadMm3 (
223 VOID
224 )
225 {
226 UINT64 Data;
227
228 __asm__ __volatile__ (
229 "movd %%mm3, %0 \n\t"
230 : "=r" (Data) // %0
231 );
232
233 return Data;
234 }
235
236 /**
237 Reads the current value of 64-bit MMX Register #4 (MM4).
238
239 Reads and returns the current value of MM4. This function is only available
240 on IA-32 and X64.
241
242 @return The current value of MM4.
243
244 **/
245 UINT64
246 EFIAPI
247 AsmReadMm4 (
248 VOID
249 )
250 {
251 UINT64 Data;
252
253 __asm__ __volatile__ (
254 "movd %%mm4, %0 \n\t"
255 : "=r" (Data) // %0
256 );
257
258 return Data;
259 }
260
261 /**
262 Reads the current value of 64-bit MMX Register #5 (MM5).
263
264 Reads and returns the current value of MM5. This function is only available
265 on IA-32 and X64.
266
267 @return The current value of MM5.
268
269 **/
270 UINT64
271 EFIAPI
272 AsmReadMm5 (
273 VOID
274 )
275 {
276 UINT64 Data;
277
278 __asm__ __volatile__ (
279 "movd %%mm5, %0 \n\t"
280 : "=r" (Data) // %0
281 );
282
283 return Data;
284 }
285
286 /**
287 Reads the current value of 64-bit MMX Register #6 (MM6).
288
289 Reads and returns the current value of MM6. This function is only available
290 on IA-32 and X64.
291
292 @return The current value of MM6.
293
294 **/
295 UINT64
296 EFIAPI
297 AsmReadMm6 (
298 VOID
299 )
300 {
301 UINT64 Data;
302
303 __asm__ __volatile__ (
304 "movd %%mm6, %0 \n\t"
305 : "=r" (Data) // %0
306 );
307
308 return Data;
309 }
310
311 /**
312 Reads the current value of 64-bit MMX Register #7 (MM7).
313
314 Reads and returns the current value of MM7. This function is only available
315 on IA-32 and X64.
316
317 @return The current value of MM7.
318
319 **/
320 UINT64
321 EFIAPI
322 AsmReadMm7 (
323 VOID
324 )
325 {
326 UINT64 Data;
327
328 __asm__ __volatile__ (
329 "movd %%mm7, %0 \n\t"
330 : "=r" (Data) // %0
331 );
332
333 return Data;
334 }
335
336 /**
337 Writes the current value of 64-bit MMX Register #0 (MM0).
338
339 Writes the current value of MM0. This function is only available on IA32 and
340 X64.
341
342 @param Value The 64-bit value to write to MM0.
343
344 **/
345 VOID
346 EFIAPI
347 AsmWriteMm0 (
348 IN UINT64 Value
349 )
350 {
351 __asm__ __volatile__ (
352 "movd %0, %%mm0" // %0
353 :
354 : "m" (Value)
355 );
356 }
357
358 /**
359 Writes the current value of 64-bit MMX Register #1 (MM1).
360
361 Writes the current value of MM1. This function is only available on IA32 and
362 X64.
363
364 @param Value The 64-bit value to write to MM1.
365
366 **/
367 VOID
368 EFIAPI
369 AsmWriteMm1 (
370 IN UINT64 Value
371 )
372 {
373 __asm__ __volatile__ (
374 "movd %0, %%mm1" // %0
375 :
376 : "m" (Value)
377 );
378 }
379
380 /**
381 Writes the current value of 64-bit MMX Register #2 (MM2).
382
383 Writes the current value of MM2. This function is only available on IA32 and
384 X64.
385
386 @param Value The 64-bit value to write to MM2.
387
388 **/
389 VOID
390 EFIAPI
391 AsmWriteMm2 (
392 IN UINT64 Value
393 )
394 {
395 __asm__ __volatile__ (
396 "movd %0, %%mm2" // %0
397 :
398 : "m" (Value)
399 );
400 }
401
402 /**
403 Writes the current value of 64-bit MMX Register #3 (MM3).
404
405 Writes the current value of MM3. This function is only available on IA32 and
406 X64.
407
408 @param Value The 64-bit value to write to MM3.
409
410 **/
411 VOID
412 EFIAPI
413 AsmWriteMm3 (
414 IN UINT64 Value
415 )
416 {
417 __asm__ __volatile__ (
418 "movd %0, %%mm3" // %0
419 :
420 : "m" (Value)
421 );
422 }
423
424 /**
425 Writes the current value of 64-bit MMX Register #4 (MM4).
426
427 Writes the current value of MM4. This function is only available on IA32 and
428 X64.
429
430 @param Value The 64-bit value to write to MM4.
431
432 **/
433 VOID
434 EFIAPI
435 AsmWriteMm4 (
436 IN UINT64 Value
437 )
438 {
439 __asm__ __volatile__ (
440 "movd %0, %%mm4" // %0
441 :
442 : "m" (Value)
443 );
444 }
445
446 /**
447 Writes the current value of 64-bit MMX Register #5 (MM5).
448
449 Writes the current value of MM5. This function is only available on IA32 and
450 X64.
451
452 @param Value The 64-bit value to write to MM5.
453
454 **/
455 VOID
456 EFIAPI
457 AsmWriteMm5 (
458 IN UINT64 Value
459 )
460 {
461 __asm__ __volatile__ (
462 "movd %0, %%mm5" // %0
463 :
464 : "m" (Value)
465 );
466 }
467
468 /**
469 Writes the current value of 64-bit MMX Register #6 (MM6).
470
471 Writes the current value of MM6. This function is only available on IA32 and
472 X64.
473
474 @param Value The 64-bit value to write to MM6.
475
476 **/
477 VOID
478 EFIAPI
479 AsmWriteMm6 (
480 IN UINT64 Value
481 )
482 {
483 __asm__ __volatile__ (
484 "movd %0, %%mm6" // %0
485 :
486 : "m" (Value)
487 );
488 }
489
490 /**
491 Writes the current value of 64-bit MMX Register #7 (MM7).
492
493 Writes the current value of MM7. This function is only available on IA32 and
494 X64.
495
496 @param Value The 64-bit value to write to MM7.
497
498 **/
499 VOID
500 EFIAPI
501 AsmWriteMm7 (
502 IN UINT64 Value
503 )
504 {
505 __asm__ __volatile__ (
506 "movd %0, %%mm7" // %0
507 :
508 : "m" (Value)
509 );
510 }
511
512 /**
513 Reads the current value of Time Stamp Counter (TSC).
514
515 Reads and returns the current value of TSC. This function is only available
516 on IA-32 and X64.
517
518 @return The current value of TSC
519
520 **/
521 UINT64
522 EFIAPI
523 AsmReadTsc (
524 VOID
525 )
526 {
527 UINT32 LowData;
528 UINT32 HiData;
529
530 __asm__ __volatile__ (
531 "rdtsc"
532 : "=a" (LowData),
533 "=d" (HiData)
534 );
535
536 return (((UINT64)HiData) << 32) | LowData;
537 }