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